SpringBoot配置加載,各配置文件優先級對比方式
1.SpringBoot配置文件
SpringBoot使用一個以application命名的配置文件作為默認的全局配置文件。支持properties後綴結尾的配置文件或者以yml/yaml後綴結尾的YAML的文件配置。
以設置應用端口為例
properties文件示例(application.properties):
server.port=80
YAML文件示例(application.yml):
server: port: 80
yaml語法規范這裡不多說
兩者同時存在情況
假如各配置文件都配置瞭不同的端口,那麼SpringBoot會使用哪一個端口呢?帶著疑問試驗一下實例
- 在resources目錄下創建兩個配置文件,一個為application.yml配置文件,設置端口為8010,另一個為application.properties配置文件,設置端口為8020;
- 重啟系統;
- 運行結果:
- 結論:可見在同一目錄下,properties配置優先級 > YAML配置優先級。//所以我們在jar包啟動時帶上properties寫法的配置可以覆蓋配置
2.配置文件目錄
SpringBoot配置文件可以放置在多種路徑下,不同路徑下的配置優先級有所不同。可放置目錄(優先級從高到低)
- file:./config/ (當前項目路徑config目錄下);
- file:./ (當前項目路徑下);
- classpath:/config/ (類路徑config目錄下);
- classpath:/ (類路徑config下).
優先級由高到底,高優先級的配置會覆蓋低優先級的配置;
SpringBoot會從這四個位置全部加載配置文件並互補配置;
我們可以從ConfigFileApplicationListener這類便可看出,其中DEFAULT_SEARCH_LOCATIONS屬性設置瞭加載的目錄:
private static final String DEFAULT_SEARCH_LOCATIONS = "classpath:/,classpath:/config/,file:./,file:./config/";
接著getSearchLocations方法中去逗號解析成Set,其中內部類Loader負責這一配置文件的加載過程,包括加載profile指定環境的配置,以application+’-‘+name格式的拼接加載。
多種目錄配置同時存在情況
接下來還是以端口配置為例
- 在resources/目錄下配置文件設置端口為8888;
- 在resources/config目錄下配置文件設置端口為9999;
- 在項目路徑下配置文件設置端口為6666;
- 在項目路徑config目錄下配置文件設置端口為7777;
最終運行結果:
Tomcat started on port(s): 7777 (http) with context path ‘/beedo’
Started BeedoApplication in 4.544 seconds (JVM running for 5.335)
通過控制變量法得以論證
其優先級由高到底,高優先級的配置會覆蓋低優先級的配置
3.自定義配置屬性
SpringBoot提供瞭許多的配置,但通常情況我們需要自定義自己的配置應用自己的系統中,如你需要配置一個默認的用戶名密碼做為系統的登錄用。
首先創建一個實體類,作為配置註入用,並使用**@ConfigurationProperties註解進行批量註入, 也可以使用Spring底層註解
@Value(“${user.username}”)**的方式一個一個註入達到同意的效果
@Component @ConfigurationProperties(prefix = "user") public class Login{ private String username; private String password; ... }
或者@Value寫法
@Component public class Login{ private String username; private String password; ... }
配置yaml文件
user: username: admin password: 123
或者properties文件
login.username=admin login.password=123
編寫一個junit測試用例,看看配置的值是否正常註入:
@RunWith(SpringRunner.class) @SpringBootTest public class DeployApplicationTests { @Autowired private Login login; @Test public void contextLoads() { System.out.println(login); } }
從輸出結果上看,值已正常註入
Login{username=‘admin’, password=‘123′}
比較項 | @ConfigurationProperties | @Value |
---|---|---|
全量註入 | 支持 | 否 |
松散綁定(Relaxed binding) | 支持 | 否 |
SpEL | 否 | 支持 |
JSR303 | 支持 | 不支持 |
**松散綁定:**駝峰命名(userName)、橫幹拼接(user-name)、下劃線(user_name)之間可以互相識別綁定稱為做松散綁定 **JSR303:**通過@Email,@Nullable,@Digits 等等註解進行郵箱、判空、數字格式等等數據的校驗,更多相關內容請參考IBM的中文文檔:https://www.ibm.com/developerworks/cn/java/j-lo-jsr303/index.html @ConfigurationProperties通常用於將配置全量註入某個類中; @Value通常用於註入某一些特定配置值中;
自定義配置提示
在編寫配置時,你會發現自定義配置沒有提示,讓你在使用自定義配置時變的很麻煩,其實SpringBoot早已為我們準備好瞭提示的需要,隻需要用引入相關依賴即可有提示。
在沒有加入依賴時idea會有如下提示:
添加依賴,該idea提示便消失,編寫自定義配置時也有相應提示:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
需要運行一下
4.指定配置文件
通常情況下我們將配置配置在application開頭的主配置文件中,這樣隨著項目的增大配置項的增多會使文件變得非常臃腫,其實SpringBoot早已考慮到瞭該問題,SpringBoot提供瞭**@PropertySource和@ImportResource**兩個註解用於加載外部配置文件使用。
- @PropertySource通常用於屬性加載配置文件,註意@PropertySource註解不支持加載yaml文件,支持properties文件。
- @ImportResource通常用於加載Spring的xml配置文件
@PropertySource使用
裝配properties配置文件
在sources/config下創建一個yaml文件命名為user.properties內容與上方user的配置一樣
Login類可如下寫法
@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); } }
其他問題
idea使用*.properties文件出現中文亂碼問題?
idea對*.properties默認編碼為GBK,通常我們項目為UTF-8編碼,這樣程序在讀取時就會出現亂碼問題;
解決方法:
idea 中 打開如下選項File->Sttings->Editor->FileEncodings
將GBK修改為UTF-8並勾選
Transparent native-to ascill conversion(在運行的時候轉換成ascii碼)
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- SpringBoot @PropertySource與@ImportResource有什麼區別
- springboot默認的5種加載路徑詳解
- SpringBoot框架配置文件路徑設置方式
- Springboot-yaml配置和自動配置原理分析
- SpringBoot實現配置文件的替換