SpringBoot读取配置文件顺序

35 篇文章 1 订阅
31 篇文章 1 订阅

一、前言

本文通过源码分析 SpringBoot 加载配置文件目录的顺序,以及 properties、xml、yml、yaml文件的读取顺序

二、SpringBoot配置文件目录读取顺序

配置文件目录读取顺序(由高到低):

  1. file:./config/ 当前项目下的/config目录
  2. file:./ 当前项目的根目录
  3. classpath:/config/ classpath的/config目录
  4. classpath:/ classpath的根目录

源码解析

我们从 SpringApplication.run 开始,一直往里走,来到 run(java.lang.String...) 方法,如下

image-20230727153319679

加载配置文件属于准备环境,我们继续跟进 prepareEnvironment 方法

image-20230727153442043

这里在环境准备就绪之后,会触发 environmentPrepared 事件,我们跟进 listeners.environmentPrepared(environment); 方法

image-20230727153847555

这里循环了所有的 SpringApplicationRunListener 调用其 environmentPrepared 方法,这个 listeners 其实就是读取 META-INF 目录下的 spring.factories 文件里的 org.springframework.boot.SpringApplicationRunListener,见下图

image-20230727154750488

ps:这里其实也是一个扩展点,如果你需要在环境准备就绪后,做一些自定义的操作,就可以自己写个类实现 SpringApplicationRunListener 接口,然后在自己的项目 /META-INF 目录下创建一个名为 spring.factories 的文件,在文件中添加 org.springframework.boot.SpringApplicationRunListener=自定义类的全路径

扯回来,我们知道这里的 listeners 其实就是 EventPublishingRunListener (见图),继续跟进其 environmentPrepared 方法

image-20230727155553838

这里调用了 Spring 的事件广播器去做事件广播,注意这里事件类是 ApplicationEnvironmentPreparedEvent 后面有用,继续跟进 multicastEvent 方法

image-20230727155759283

这里就是 Spring 事件广播的标准写法了,根据 event 找到匹配的 ApplicationListener,调用 invokeListener 方法,进去再调用 doInvokeListener 方法,最后会调用到 ApplicationListeneronApplicationEvent 方法,具体怎么找到这些 ApplicationListener 的,这里就不展开了,在众多匹配的 ApplicationListener 里有一个 ConfigFileApplicationListener ,看名字就知道,专门用来处理配置文件的,我们看它的 onApplicationEvent 方法

image-20230727162005026

上面我们知道事件类是 ApplicationEnvironmentPreparedEvent,所以这里走的是 onApplicationEnvironmentPreparedEvent 方法,继续跟进

image-20230727164746928

这里又从 spring.factories 文件里获取了 org.springframework.boot.env.EnvironmentPostProcessor,并且把自己(ConfigFileApplicationListener)也算进去了,因为 ConfigFileApplicationListener 也实现了 EnvironmentPostProcessor 接口,然后执行了这些 EnvironmentPostProcessorpostProcessEnvironment 方法,我们这里还是重点看 ConfigFileApplicationListenerpostProcessEnvironment 方法

image-20230727165041251

继续跟进 addPropertySources 方法

image-20230727165120996

继续跟进 load 方法

image-20230727170624833

这个方法里 initializeProfiles 方法会根据 spring.profiles.active 配置来决定加载哪个配置文件,如果没有就用 spring.profiles.default 配置,如果配的是 dev,就加载 application-dev.propertiesapplication-dev.yml 这样的配置文件,如果这两个参数都没有配,就加载 application.propertiesapplication.yml 这样的配置文件,下面具体看加载的逻辑里是如何获取目录的,跟进 load 方法

image-20230727174057481

很明显了,获取扫描目录的代码在 getSearchLocations 方法里

image-20230727174159191

可以看到返回值正是这4个目录,这个值一般都是取自 DEFAULT_SEARCH_LOCATIONS 这个常量,我们看下

image-20230727174326837

这里需要注意,这个常量是按优先级从低到高倒序排列的。

三、SpringBoot配置文件类型读取顺序

配置文件类型读取顺序(由高到低):

  1. properties
  2. xml
  3. yml
  4. yaml

源码解析

在上面我们讲到获取目录,下面就是要循环每个目录,在每个目录下找配置文件了,那么配置文件类型有好几种,读取的先后顺序是怎样的呢,我们先找到 load 方法

image-20230727175410839

可以看到循环中又调用了 load 方法,跟进

image-20230727175912993

可以看到走进了一个双层嵌套循环,循环调用了 loadForFileExtension 方法,方法里就是具体加载文件的源码了,我们这里重点关注的是文件类型的读取顺序,就不深究加载文件的源码了,我们看这个双层嵌套的循环,分别循环的是什么,先是循环的 propertySourceLoaders,然后再循环 loader 的 getFileExtensions 方法返回的 String 数组,这个 propertySourceLoaders 是什么呢,我们发现又又是读取的 spring.factories 文件,这回读的是 org.springframework.boot.env.PropertySourceLoader,在文件的最上面

image-20230727180524129

可以看到先后顺序是 PropertiesPropertySourceLoaderYamlPropertySourceLoader,我们再分别看这两个 loader 的 getFileExtensions 方法

image-20230727180709878

image-20230727180800564

结论很明显了,顺序是 properties > xml > yml > yaml。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

每天进步亿点点的小码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值