springboot讀取配置文件總結


一、配置文件優先級加載機制

spring boot 啟動會掃描以下位置的application.properties或者application.yml文件作為Spring boot的默認配置文件。

–file:./config/
–file:./
–classpath:/config/
–classpath:/

加載的優先級順序是從上向下加載,並且所有的文件都會被加載,高優先級的內容會覆蓋底優先級的內容,形成互補配置。

PS:不過需要注意的是在工程根路徑下或者根路徑的config下面的配置文件,在工程打包時候不會被打包進去(這也可能和項目級別有關系,Module級別與IDEA中Project級別的,待驗證,未實操)。

我們可以從ConfigFileApplicationListener這類便可看出,其中DEFAULT_SEARCH_LOCATIONS屬性設置了加載的目錄:

private static final String DEFAULT_SEARCH_LOCATIONS = "classpath:/,classpath:/config/,file:./,file:./config/";

接着getSearchLocations方法中去逗號解析成Set,其中內部類Loader負責這一配置文件的加載過程,包括加載profile指定環境的配置,以application+’-’+name格式的拼接加載。


 下圖所示:

 

以上是按照優先級從高到低(1-4)的順序,所有位置的文件都會被加載,高優先級配置內容會覆蓋低優先級配置內容。

PS:項目目錄的config下面的application.yml和項目根目錄下的application.yml掃描不進去,可能是因為你用的項目是Module級別的,你必須使用IDEA中Project級別的項目才能掃描到項目根路徑下的東西(待驗證,未實操)。

我們也可以通過配置spring.config.location來改變默認配置。

java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --spring.config.location=D:/application.properties

另外也可以通過命令行參數進行配置:

  • 所有的配置都可以在命令行上進行指定;
  • 多個配置用空格分開; --配置項=值
java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar 
--server.port=8087 --server.context-path=/abc

以下優先級從高到底加載順序:

  1.命令行參數

  2.來自java:comp/env的JNDI屬性
  3.Java系統屬性(System.getProperties())
  4.操作系統環境變量
  5.RandomValuePropertySource配置的random.*屬性值
  6.jar包外部的application-{profile}.properties或application.yml(帶spring.profile)配置文件
  7.jar包內部的application-{profile}.properties或application.yml(帶spring.profile)配置文件
  8.jar包外部的application.properties或application.yml(不帶spring.profile)配置文件
  9.jar包內部的application.properties或application.yml(不帶spring.profile)配置文件

    Note:由jar包外向jar包內進行尋找,優先加載帶profile的,再加載不帶profile的。
  10.@Configuration注解類上的@PropertySource
  11.通過SpringApplication.setDefaultProperties指定的默認屬性

參考官網地址官網圖示如下:

二、properties配置優先級 > YAML配置優先級 

  SpringBoot使用一個以application命名的配置文件作為默認的全局配置文件。支持properties后綴結尾的配置文件或者以yml/yaml后綴結尾的YAML的文件配置。
以設置應用端口為例
properties文件示例(application.properties):

server.port=80

YAML文件示例(application.yml):

server:
  port: 80

yaml語法規范可以參照該篇文章:https://blog.csdn.net/it_faquir/article/details/79842885

兩者同時存在情況
假如各配置文件都配置了不同的端口,那么SpringBoot會使用哪一個端口呢?帶着疑問試驗一下實例

在resources目錄下創建兩個配置文件,一個為application.yml配置文件,設置端口為8010,另一個為application.properties配置文件,設置端口為8020;
重啟項目后運行結果:

結論:可見在同一目錄下,properties配置優先級 > YAML配置優先級。//所以我們在jar包啟動時帶上properties寫法的配置可以覆蓋配置。

三、@PropertySource和@ImportResource

  通常情況下我們將配置配置在application開頭的主配置文件中,這樣隨着項目的增大配置項的增多會使文件變得非常臃腫,其實SpringBoot早已考慮到了該問題,SpringBoot提供了**@PropertySource和@ImportResource**兩個注解用於加載外部配置文件使用。

  • @PropertySource通常用於屬性加載配置文件,注意@PropertySource注解不支持加載yaml文件,支持properties文件。
  • @ImportResource通常用於加載Spring的xml配置文件

@PropertySource使用

裝配properties配置文件
在sources/config下創建一個yaml文件命名為user.properties內容與上方user的配置一樣

@PropertySource(value = {"classpath:config/user.properties"})
@Component
@ConfigurationProperties(prefix = "user")
public class Login{
private String username;
private String password;
...
}

同時加載多個配置問題
細心的你,會發現@PropertySource注解中屬性value為一個數組,如果同時加載多個配置文件,並且不同配置文件中對同一個屬性設置了不同的值,那么Spring會識別哪一個呢?
帶着疑問,我們可以通過控制變量法進行測試,具體過程再在贅述。

@PropertySource(value = {"classpath:config/user1.properties","classpath:config/user2.properties"})

結論:Spring加載順序為從左到右順序加載,后加載的會覆蓋先加載的屬性值。

配yaml配置文件
  如果你有強迫症,一定想加載yaml配置文件,那么可以通過PropertySourcesPlaceholderConfigurer類來加載yaml文件,將原來的user.properties改成user.yaml,Bean配置類中加入如下代碼,Login配置類和一開始的方式一致。

@Bean
public static PropertySourcesPlaceholderConfigurer loadProperties() {
    PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
    YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
    //yaml.setResources(new FileSystemResource("classpath:config/user.yml"));//File路徑引入
    yaml.setResources(new ClassPathResource("config/user.yml"));//class路徑引入
    configurer.setProperties(yaml.getObject());
    return configurer;
}

運行一下,仍然可以能達到加載配置效果的。

@ImportResource使用

  SpringBoot提出零xml的配置,因此SpringBoot默認情況下是不會主動識別項目中Spring的xml配置文件。為了能夠加載xml的配置文件,SpringBoot提供了@ImportResource注解該注解可以加載Spring的xml配置文件,通常加於啟動類上。

@ImportResource(value = {"classpath:/beans.xml"})
@SpringBootApplication(scanBasePackages = {"team.seagull.client"})
public class DeployApplication {
    public static void main(String[] args) {
        SpringApplication.run(DeployApplication.class, args);
    }
}

四、一般配置文件方案參考

  我在自己的springboot項目中使用了多個配置文件,application.properties是主配置文件,放一些項目通用的配置,application-dev.properties 放的是平常開發的一些配置,比如說數據庫的連接地址、帳號密碼等,

application-prod.properties 放的是生產環境的一些配置,比如說數據庫的連接地址、帳號密碼等,

當然也可以再多一個application-test.properties ,放一些測試環境需要用到的參數。

可以通過在application.properties 中設置spring.profiles.active=prod或者dev來使用application-dev.properties或者application-prod.properties文件,當然test文件也是同理。

五、其他問題

idea使用*.properties文件出現中文亂碼問題?
idea對*.properties默認編碼為GBK,通常我們項目為UTF-8編碼,這樣程序在讀取時就會出現亂碼問題;
解決方法:idea 中 打開如下選項File->Sttings->Editor->FileEncodings

將GBK修改為UTF-8並勾選
Transparent native-to ascill conversion(在運行的時候轉換成ascii碼)

 

 

 

 參考文章:

 https://blog.csdn.net/J080624/article/details/80508606

 https://blog.csdn.net/it_faquir/article/details/80869578

 https://blog.csdn.net/huangyuehong914/article/details/80521917


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM