SpringBoot 配置加载优先级详解

一、概述

本文是网上查了查相关资料,这里整理记录一下,方便总结归纳。

主要针对 spring.profiles.activespring.config.location 以及 spring.config.additional-location 的作用机制及优先级问题进行实践对比。

二、配置文件优先级介绍

2.1 加载位置与顺序

SpringBoot启动会扫描以下位置的application.properties/yml文件作为spring boot的默认配置文件:

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

以上是按照优先级从高到低的顺序,所有位置的文件都会被加载,高优先级配置内容会覆盖低优先级配置的内容,并形成互补配置;当然,我们也可以通过spring.config.location来改变默认配置。

上面的:

  • file: 指当前项目根目录
  • classpath: 指当前项目的resources目录

给出一个图例:

 注意: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

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot配置文件非常灵活,可以根据需要选择不同的文件进行配置Spring Boot配置文件分为两种:application.properties 和 application.yml。两种配置文件的优先级是相同的,都可以用来配置 Spring Boot 的应用程序。 首先,Spring Boot 会从 application.properties 和 application.yml 文件中读取配置信息,如果在 application.properties 和 application.yml 中都有同名的属性,则 application.yml 中的配置会覆盖 application.properties 中的配置。 其次,Spring Boot 会从外部配置文件中读取配置信息。外部配置文件可以指定在启动命令中,例如: ``` java -jar myapp.jar --spring.config.name=myapp --spring.config.location=file:/opt/myapp/config/ ``` 这条命令告诉 Spring Boot 使用 myapp.properties 或 myapp.yml 作为配置文件,并且从 /opt/myapp/config/ 目录中读取配置信息。同样,如果一个属性在外部配置文件中被定义,则会覆盖 application.properties 和 application.yml 中的配置。 最后,Spring Boot 会从命令行参数中读取配置信息。例如,生成的 jar 包可以使用以下命令运行: ``` java -jar myapp.jar --server.port=8081 --debug=true ``` 这条命令告诉 Spring Boot 使用 8081 端口启动应用程序,并且启用调试模式。同样,命令行参数中的属性会覆盖所有其他配置信息。 总的来说,Spring Boot配置文件优先级为:命令行参数 > 外部配置文件 > application.yml > application.properties。在实际开发中,我们可以根据需要灵活选择不同的配置方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值