赞
踩
本文是网上查了查相关资料,这里整理记录一下,方便总结归纳。
主要针对 spring.profiles.active
、spring.config.location
以及 spring.config.additional-location
的作用机制及优先级问题进行实践对比。
SpringBoot启动会扫描以下位置的application.properties/yml文件作为spring boot的默认配置文件:
- file:./config/
- file:./
- classpath:/config/
- classpath:/
以上是按照优先级从高到低的顺序,所有位置的文件都会被加载,高优先级配置内容会覆盖低优先级配置的内容,并形成互补配置;当然,我们也可以通过spring.config.location来改变默认配置。
上面的:
给出一个图例:
注意:maven打包是不能把src外面的两个application.properties文件打到jar包里的。
2.2 配置说明
2.2.1 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=appNameInner
- testKey=key-default
application-dev.properties 文件配置
testKey=key-dev
通过以下代码在启动时将配置值输出:
- @Value("${testKey}")
- private String testKey;
-
- @PostConstruct
- private void init(){
- System.out.println("-------------------------------");
- System.out.println(testKey);
- System.out.println("-------------------------------");
- }
2.1.1 不指定 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,则使用默认的。
2.1.2 指定 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 中的配置值。
2.2 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-properties
- testKey=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 操作。
2.2.1 另外
SpringApplication 将会从如下位置加载application.properties到spring的环境变量中:
当前目录的子目录/config下
当前目录
类路径的/config下
应用根目录下
上述也是其优先使用顺序。 如果不想使用application.properties作为其配置文件名字,可以通过配置环境变量spring.config.name进行设置。也可以通过具体化位置的环境变量spring.config.location其指定:如下代码
#通过第一种方式
java -jar myproject.jar --spring.config.name=myproject
##方式二
java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
如果spring.config.location 也包含具体目录,需要使用“/”. spring.config.location 不支持具体额配置环境变量,将会被默认的配置环境变量替换。其配置搜索的顺序与配置的顺序刚好相反。例如:配置顺序为:classpath:/,classpath:/config/,file:./,file:./config/,其搜索顺序如下:
file:./config/
file:./
classpath:/config/
classpath:/
2.3 spring.config.additional-location
在使用 spring.config.additional-location 这种方式自定义 locations 时,除了默认 locations 之外,还会使用 spring.config.additional-location 指定的。
additional-location:言外之意就是增量的配置
例如追加的目录为 classpath:/custom-config/,file:./custom-config/,其搜索的顺序如下:
file:./custom-config/
classpath:custom-config/
file:./config/
file:./
classpath:/config/
classpath:/
(备注,我们也可以通过配置环境变量的形式来进行配置)
在工程的根目录的 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 中的配置值。
2.4 spring.config.additional-location 与 spring.profiles.active 配置加载关系
spring.config.location 不用多数,它就是独立的一份,使用它就不能使用其它的。所以这里只分析 spring.config.additional-location 与 spring.profiles.active 配置加载关系。
2.4.1 同时指定两个配置
通过 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 要高。
2.4.2 `spring.config.additional-location` 指定差异增量配置
在 spring.config.additional-location 中增加 additionKey
testKey=key-addition
additionKey=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-dev
testAddition
-------------------------------
结论是 spring.config.additional-location 可以用于提供出 profiles 机制或者默认方式之外的增量配置。
3 springboot如何同时加载多个配置文件
springboot 默认是在src/main/resources文件夹中加载application.properties默认配置文件,格式为application-{profile}.properties,其中{profile}对应你的环境标识
在application.properties中添加spring.profiles.active = dev,database
# 加载多个配置文件,系统加载了application.properties application-database.properties application-dev.properties 三个配置文件
spring.profiles.active = dev,database
系统加载了src/main/resources目录下的application.properties application-database.properties application-dev.properties 三个配置文件
4 引用官方的文档说明:
If you don’t like application.properties as the configuration file name you can switch to another by specifying a spring.config.name environment property. You can also refer to an explicit location using the spring.config.location environment property (comma-separated list of directory locations, or file paths).
$ java -jar myproject.jar --spring.config.name=myproject
or
$ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
spring.config.name and spring.config.location are used very early to determine which files have to be loaded so they have to be defined as an environment property (typically OS env, system property or command line argument).
If spring.config.location contains directories (as opposed to files) they should end in / (and will be appended with the names generated from spring.config.name before being loaded, including profile-specific file names). Files specified in spring.config.location are used as-is, with no support for profile-specific variants, and will be overridden by any profile-specific properties.
The default search path classpath:,classpath:/config,file:,file:config/ is always used, irrespective of the value of spring.config.location. This search path is ordered from lowest to highest precedence (file:config/ wins). If you do specify your own locations, they take precedence over all of the default locations and use the same lowest to highest precedence ordering. In that way you can set up default values for your application in application.properties (or whatever other basename you choose with spring.config.name) and override it at runtime with a different file, keeping the defaults.
默认将从以下位置加载配置文件spring.config.location=classpath:application.properties,classpath:config/application.properties,多个文件路径以逗号间隔。
如果路径以最后为目录,必须以"/"结尾。spring.config.location=classpath:config/,那么spring.config.name会自动追加到后面!一旦设定了spring.config.location属性,上述的默认位置将不起作用!因为你要修改的是application.properties的名称,所以上面的两个属性建议通过命令行的方式配置,如:
java -jar trade-web-0.0.1-SNAPSHOT-f1f86f1.jar --spring.config.location=/var/www/config/ --spring.config.name=application.properties
java -jar trade-web-0.0.1-SNAPSHOT-f1f86f1.jar --spring.config.location=/var/www/config/application.properties
5. 小结
在使用外部化配置文件时,执行顺序为:
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 则不会。
6. 参考:
https://github.com/glmapper/springboot-series-guides/tree/master/guides-properties
http://www.glmapper.com/2020/01/03/springboot-series-externalize-prop/
https://juejin.im/entry/5a4b33e6518825258227bfbe
https://blog.csdn.net/hbiao68/article/details/87360551
https://blog.csdn.net/Alan666156/article/details/53404792
————————————————
版权声明:本文为CSDN博主「zzhongcy」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zzhongcy/article/details/107200796
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。