一文读懂SpringBoot配置的加载机制、优先级、外部化配置

引言

SpringBoot的配置文件最常见的就是 application.propertiesapplication.yml,一般都是放在 src/main/resources 目录下。
那么问题来了:

  1. 如果多个配置文件存在同名的配置key,最终生效的值会采用哪个文件的?
  2. 不同文件格式的配置存在同名的配置key,最终生效的值会采用哪个文件的?
  3. 打成jar后部署运行时,需要修改某些配置(eg:数据库信息)怎么办?难道要解压jar去改里面的配置文件?

这便是本文要探究的问题,关于配置的优先级以及加载机制。我们先用一些案例来观察实际效果,后面再深入源码进行印证。走起

遇事不决,先打日志!

如果你用的是 application.properties,添加以下配置:

logging.level.org.springframework.boot.context.config.ConfigFileApplicationListener = trace

如果你用的是 application.yml,添加以下配置:

logging.level.org.springframework.boot.context.config.ConfigFileApplicationListener: trace

重新启动服务,你会发现新大陆:
在这里插入图片描述
这日志给你安排的明明白白,从日志我们可以得到这么些信息:

  1. 配置的加载路径有四个地方,分别是 file:./config/file:./classpath:/config/classpath:/
  2. 配置文件格式有四种,分别是 propertiesxmlymlyaml

我项目是用了application.yml,放在 src/main/resources中,也就是对应日志中的 classpath:/application.yml,可以看到它也确实被加载到了(图中倒数第二行)。

试验

从日志的打印顺序就可以直观的看出配置的加载顺序,但是没法知道它的优先级。这就得实践出真知了。上代码

相同文件格式,不同加载路径

  1. 在 src/main/resources/application.yml (对应 classpath:/ 路径)增加如下配置
key: classpath:/application.yml
  1. 在 src/main/resources/config/application.yml (对应 classpath:/config/ 路径)增加如下配置
key: classpath:/config/application.yml
  1. 编写打印配置的代码
    @Bean
    public ApplicationRunner test(Environment env){
        return new ApplicationRunner() {
            @Override
            public void run(ApplicationArguments args) throws Exception {
                System.out.println(env.getProperty("key"));
            }
        };
    }
  1. 运行服务,最终打印的结果是 classpath:/config/application.yml

说明:相同文件格式的情况下,classpath:/config/ 优先级 高于 classpath:/

相同加载路径,不同文件格式

  1. 在上一节的代码做以下调整
  2. 删掉上一节创建的 src/main/resources/config/application.yml
  3. 在 src/main/resources/application.properties 增加如下配置
key=classpath:/application.properties
  1. 运行服务,最终打印的是 classpath:/application.properties

说明:相同加载路径的情况下,properties 优先级 高于 yml

不同加载路径,不同文件格式

  1. 在上一节的代码做以下调整
  2. 还原 src/main/resources/config/application.yml
  3. 运行服务,最终打印的是 classpath:/config/application.yml

说明:虽然 properties > yml,但是 classpath:/config/ > classpath:/,最终classpath:/config/application.yml > classpath:/application.properties,侧面得出加载路径权重高于文件格式。

总结

根据上面的试验结果,以及日志中体现的加载顺序,我们可以得出以下结论:(上述试验仅测了其中几种情况,有兴趣的同学可以挨个试验)

加载路径的优先级

加载路径的优先级:file:./config/ > file:./ > classpath:/config/ > classpath:/

文件格式的优先级

文件格式的优先级:properties > xml > yml > yaml

扩展:外部化配置

一般我们SpringBoot打成jar包,配置文件是内置在jar中的,需要修改某些配置项如果要去改jar包,那稍显麻烦。SpringBoot自然意识到这个问题,默认的加载路径 file:./config/file:./ 便是外部化配置的关键。也就是SpringBoot jar启动时会去当前目录下./config/./路径读取配置文件,若有配置文件,根据优先级会替换jar包中的同名配置。


end
下一篇,将带大家深入到源码,看看SpringBoot从代码层面是如何实现的。敬请期待…

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值