本文主要針對 spring.profiles.active、spring.config.location 以及
spring.config.additional-location 的作用機制及優先級問題進行實踐對比。
本文案例工程已上傳 github 倉庫:
https://github.com/glmApper/springboot-series-guides/tree/master/guides-properties
spring.profiles.active
除了 application.properties 文件之外,profile-specific 配置也可以通過以下命名方式來定義:application-{profile}.properties。在沒有使用 active 指定 profiles 的情況下,Environment 會指定一組默認的 profiles(默認情況下是[default]),換句話說就是,如果沒有顯示的激活 profiles 配置文件,則默認加載的是
application-default.properties 配置文件。
profile-specific 配置文件的屬性與標準 application.properties 從相同的位置加載(一般是 classpath 下);profile-specific 指定的 properties 配置文件始終覆蓋默認配置。
在案例工程中(guides-properties),resources 下面包括 application.properties 和
application-dev.properties 兩份配置文件
application.properties 文件配置
spring.application.name=appNameInnertestKey=key-default
application-dev.properties 文件配置
testKey=key-dev
通過以下代碼在啟動時將配置值輸出:
@Value("${testKey}")private String testKey;@PostConstructprivate void init(){ System.out.println("-------------------------------"); System.out.println(testKey); System.out.println("-------------------------------");}復制代碼
不指定 spring.profiles.active 時
通過 JAVA -jar
guides-properties/target/guides-properties-0.0.1-SNAPSHOT.jar 啟動工程,console 輸出如下:
2020-01-04 00:08:47.279 INFO 11050 --- [ main] com.glmapper.bridge.boot.BootStrap : No active profile set, falling back to default profiles: default-------------------------------key-default-------------------------------復制代碼
結論是,如果不顯示指定 profiles,則使用默認的。
指定 spring.profiles.active 時
通過 java -jar -Dspring.profiles.active=dev
guides-properties/target/guides-properties-0.0.1-SNAPSHOT.jar 啟動工程,console 輸出如下:
2020-01-04 00:08:14.426 INFO 11040 --- [ main] com.glmapper.bridge.boot.BootStrap : The following profiles are active: dev-------------------------------key-dev-------------------------------復制代碼
結論是,在顯示指定 profiles 的情況下,會覆蓋默認 application.properties 中的配置值。
spring.config.location
在 SpringBoot 2.x 中 spring.config.location 的語義發生了變更(此項配置會導致 classpath 中的 application.properties 不再生效)。原因如下:
private Set<String> getSearchLocations() { // spring.config.location 直接使用此份文件,不會再處理其他配置文件 if (this.environment.containsProperty(CONFIG_LOCATION_PROPERTY)) { return getSearchLocations(CONFIG_LOCATION_PROPERTY); } Set<String> locations = getSearchLocations(CONFIG_ADDITIONAL_LOCATION_PROPERTY); locations.addAll( asResolvedSet(ConfigFileApplicationListener.this.searchLocations, DEFAULT_SEARCH_LOCATIONS)); return locations;}復制代碼
在工程的根目錄的 conf 目錄下新建一個
application-conf.properties 配置文件,內容如下:
testKey=key-spring.config.location復制代碼
通過 java -jar -Dspring.config.location=
conf/application-conf.properties guides-properties/target/guides-properties-0.0.1-SNAPSHOT.jar 啟動工程,發現啟動報錯,原因是因為 application-conf.properties 中沒有 配置 spring.application.name,而 spring.application.name 是在 resources 目錄下的 application.properties 中的,所以也間接說明前面提到的,會使 classpath 下的配置失效。新增 spring.application.name 之后,重新啟動工程,
spring.application.name=guides-propertiestestKey=key-spring.config.location復制代碼
輸出結果如下:
2020-01-04 00:19:12.225 INFO 11147 --- [ main] com.glmapper.bridge.boot.BootStrap : No active profile set, falling back to default profiles: default-------------------------------key-spring.config.location-------------------------------復制代碼
所以在使用 spring.config.location 指定外部配置文件時,需要此份配置文件需全量滿足當前工程運行時所需,因為它不會去與 resources 目錄下的配置文件去做 merge 操作。
spring.config.additional-location
在使用
spring.config.additional-location 這種方式自定義 locations 時,除了默認 locations 之外,還會使用 spring.config.additional-location 指定的。
additional-location:言外之意就是增量的配置
在工程的根目錄的 conf 目錄下新建一個
application-addition.properties 配置文件,內容如下:
testKey=key-addition復制代碼
通過 java -jar
-Dspring.config.additional-location=conf/application-addition.properties guides-properties/target/guides-properties-0.0.1-SNAPSHOT.jar 啟動工程,輸出結果如下:
2020-01-04 00:28:30.048 INFO 11384 --- [ main] com.glmapper.bridge.boot.BootStrap : No active profile set, falling back to default profiles: default-------------------------------key-addition-------------------------------復制代碼
結論是,會覆蓋默認 application.properties 中的配置值。
spring.config.additional-location 與 spring.profiles.active 配置加載關系
spring.config.location 不用多數,它就是獨立的一份,使用它就不能使用其它的。所以這里只分析
spring.config.additional-location 與 spring.profiles.active 配置加載關系。
同時指定兩個配置
通過 java -jar -Dspring.profiles.active=dev
-Dspring.config.additional-location=conf/application-addition.properties guides-properties/target/guides-properties-0.0.1-SNAPSHOT.jar 啟動工程,輸出如下:
2020-01-04 00:32:59.044 INFO 11451 --- [ main] com.glmapper.bridge.boot.BootStrap : The following profiles are active: dev-------------------------------key-dev-------------------------------復制代碼
為了排除與 -D 參數順序有關,也使用如下方式再執行一次:java -jar
-Dspring.config.additional-location=conf/application-addition.properties -Dspring.profiles.active=dev guides-properties/target/guides-properties-0.0.1-SNAPSHOT.jar,輸出結果與前面相同,所以可以得出,spring.profiles.active 的優先級比 spring.config.additional-location 要高。
`spring.config.additional-location` 指定差異增量配置
在
spring.config.additional-location 中增加 additionKey
testKey=key-additionadditionKey=testAddition
使用 java -jar
-Dspring.config.additional-location=conf/application-addition.properties -Dspring.profiles.active=dev guides-properties/target/guides-properties-0.0.1-SNAPSHOT.jar 啟動工程,輸出如下:
2020-01-04 11:44:42.227 INFO 12821 --- [ main] com.glmapper.bridge.boot.BootStrap : The following profiles are active: dev-------------------------------key-devtestAddition-------------------------------復制代碼
結論是
spring.config.additional-location 可以用于提供出 profiles 機制或者默認方式之外的增量配置。
小結
在使用外部化配置文件時,執行順序為:
spring.config.location > spring.profiles.active >
spring.config.additional-location > 默認的 application.proerties。
其中通過 spring.profiles.active 和
spring.config.additional-location指定的配置文件會與 默認的application.proerties merge 作為最終的配置,spring.config.location 則不會。
作者:glmapper
鏈接:
https://juejin.im/post/5e10136d5188253aae7d828c