首页 > 其他分享 >Spring boot属性文件加载和生效顺序深度分析

Spring boot属性文件加载和生效顺序深度分析

时间:2022-12-07 21:41:25浏览次数:34  
标签:顺序 Spring boot application spring 加载 properties 属性


spring boot最核心的特性就是自动化配置,我们在学习spring boot的时候,首要需要了解它的自动化配置原理,其次是属性文件的加载顺序,我认为这两点是学习spring boot的重中之中。

网上介绍spring boot属性文件的加载顺序的文章很多,但都没有从源码上深入分析。
今天和大家一起通过源码探究,spring boot属性文件的加载顺序。

这里先说明一点:
先加载的属性未必会生效,后加载的属性未必一定会覆盖先加载的属性值。

说明:
加载指的是将属性值读取加载到spring容器中的过程;
生效指的是运用加载到的属性值去初始化bean的过程。

属性值加载的顺序,和属性值生效的顺序没有必然的关系。

为什么要分析?

主要是在实际项目开发过程中,由于属性文件非常多,常常导致属性文件配置混乱,
最常遇到的问题就是:
为什么明明配置了属性,但项目启动就是怎么都不生效的问题?
所以,搞清楚属性文件的读取和生效的顺序,对日常基于spring boot的开发过程中非常重要。

源码分析

1、通过main启动类,找到doInvokeListener()方法建立断点,观察ApplicationEvent中属性源的变化情况:

说明:测试的工程注册在eurake中,并从配置中心config中加载属性。

Spring boot属性文件加载和生效顺序深度分析_java

2、最先加载的3个属性源

Spring boot属性文件加载和生效顺序深度分析_属性_02


Inlined Test Properties 单元测试属性

systemProperties JVM系统属性

SystemEnvironmentProperty 系统环境变量属性3、初始化ConfigFileApplicationListener监听器时,新加载了如下数据源

Spring boot属性文件加载和生效顺序深度分析_java_03


configurationProperties

配置属性源,这个属性源比较特殊,他不会去自己加载配置属性,而是将environment中已经加载到的属性源按顺序放入存放进来,并将自己放到propertySourceList的头部first。(不是很好理解,个人感觉可能是一种缓存机制)

random 随机数属性源

springCloudClientHostInfo spring cloud客户端host相关属性源

bootstrap-dev.properties

bootstrap.properties

defaultProperties4、加载配置中心属性

Spring boot属性文件加载和生效顺序深度分析_java_04


可以发现,配置中心属性源configService虽然是后面加载的,但是被放在了propertySourceList的头部。5、启动完成后,environment中propertySourceList的顺序

Spring boot属性文件加载和生效顺序深度分析_顺序_05


feign feign调用的属性源

systemProperties java se运行时系统属性

SystemEnvironmentProperty 系统环境变量属性

configService 配置中心属性源

configurationProperties 配置属性源

Inlined Test Properties 单元测试属性

random 随机数属性源

application-dev.propeties application-profile属性源

application.propeties application属性源

springCloudClientHostInfo spring cloud客户端host相关属性源

bootstrap-dev.propeties bootstrap-profile属性源

bootstrap.propeties bootstrap属性源

eureka/server.properties eureka服务属性源

defaultProperties 默认属性源6、读取属性文件的源码分析

Spring boot属性文件加载和生效顺序深度分析_顺序_06

springboot 启动时,会初始化各种属性源PropertySource,并把加载的属性源存放到 enviroment 的propertySourceList中。我们在获取属性时,通过遍历propertySourceList的属性源去读取属性值,获取对应属性值就直接返回(先读取先生效),所以在propertySourceList前面的属性源会优先生效。

注意propertySourceList的类型是 CopyOnWriteArrayList ,即线程安全的ArrayList

7、开启属性获取日志,监控属性获取过程

logging.level.org.springframework.core.env=trace

Spring boot属性文件加载和生效顺序深度分析_顺序_07

通过注入Environment,查看执行属性加载顺序

@SpringBootTest
@Slf4j
class DemoApplicationTests {

@Autowired
Environment environment;

@Test
void getProperties() {
System.out.println(environment.getProperty("spring.user.name"));
}
}

properties和yml配置文件加载顺序

一般在spring boot中最好统一只使用一种类型的配置文件,避免出现配置混乱。
yml配置文件具有更好的格式,更强大的功能,但是对属性文件的配置格式要求比较。格式出错导致属性读取不到的问题比较难排查,且利用属性的键值搜索指定属性时,也不是很方便。properties属性文件,好处就是简单,不容易出现格式方面的问题,便于属性查找。
假设一个项目在同一位置同时存在application.properties和application.yml文件,

且其中都含有相同的某个key,但value不同,如:

application.properties中:server.port=8001,

application.yml中:server.port=8888。

问题:springboot是否都加载这两个配置文件?如果两个文件有相同的key,取哪一个文件的value?

答: 都加载,且按properties→yml的顺序加载。

Spring boot属性文件加载和生效顺序深度分析_java_08


在看到spring.factories中,配置加载器顺序是先执行PropertiesPropertySourceLoader再到YamlPropertySourceLoader。在ConfigFileApplicationListener获取server.port这个key的value时候,可以发现两配置文件全都加载进去了,且注意顺序,application.properties文件在前。

Spring boot属性文件加载和生效顺序深度分析_顺序_09


getSource()方法获取到两个Source,先从application.properties文件中查找值,一旦找到立即返回,如果找不到再从application.yml中查找。

总结

1、spring boot中先读取的属性不一定先生效,生效的顺序是根据bean初始化时,environment中属性源propertySourceList的顺序来决定的。

2、属性源初始化读取的顺序和最后存放到environment中的propertySourceList的顺序没有必然关系。

environment.getPropertySources().addFirst(source);
environment.getPropertySources().addAfter(source1,source2);
environment.getPropertySources().addBefore(source1,source2);
environment.getPropertySources().addLast(source);

3、属性文件的读取顺序大概是:
java se运行时系统属性 ——》系统环境变量属性——》
bootstrap.properties——》bootstrap-dev.properties ——》configService 配置中心属性源——》application属性源——》 application-dev属性源

注意:
从属性源的加载顺序就可以看出,为什么我们在微服务里面,在业务服务模块进行配置中心配置的时候,一定要在bootstrap属性文件中配置了。

4、项目中yml和properties这两个格式的配置文件,一般只选用一种类型的配置文件。
如果同时配置两种,会优先加载properties的配置文件,且properties的配置属性会优先生效。

5、属性文件的生效的顺序大致是:
java se运行时系统属性 ——》 系统环境变量属性——》
configService 配置中心属性——》application-dev属性源——》 application属性源——》bootstrap-dev.properties ——》bootstrap.properties
我们在java -jar启动脚本中配置的属性,属于 java se运行时系统属性,优先级最高。

6、如果项目中发现配置的属性一直没有生效,可以参考属性源的生效顺序,看看是否出现属性覆盖的问题。
更直接的方式是通过单元测试,执行environment.getProperty(“spring.user.name”),查看属性源列表propertySourceList的顺序,并通过打印日志来判断属性值是从具体哪个属性源加载到的。

希望看完本篇文章,当再被问到spring boot属性文件的加载顺序的时候,你可以胸有成竹的款款而谈。


更多精彩,关注我吧。

Spring boot属性文件加载和生效顺序深度分析_java_10


标签:顺序,Spring,boot,application,spring,加载,properties,属性
From: https://blog.51cto.com/u_15905482/5920082

相关文章

  • jQuery、Bootstrap页面框架
    今日内容概要jQuery查找标签jQuery节点操作jQuery事件绑定Bootstrap页面框架今日内容详细jQuery查找标签1.基本选择器 $('#d1') id选择器$('.c1') clas......
  • jQuery查找标签、节点操作、事件绑定、Bootstrap页面框架
    jQuery查找标签、节点操作、事件绑定、Bootstrap页面框架一、jQuery查找标签1.各种选择器1.基本选择器$('#id')id选择器$('.c1')类(cl......
  • Bootstrap页面框架
    Bootstrap页面框架Bootstrap页面框架是已经提前写好了一大堆css和js,我们只需要引入之后按照人家规定好的操作方式即可使用所有的样式和功能。Bootstrap链接:https://v3.b......
  • 前端 jQuery与Bootstrap
    jQuery查找标签//1.基本选择器$('#d1')id选择器$('.c1')class选择器$('div')标签选择器$("*")......
  • 前端之Bootstrap框架
    Bootstrap页面框架别人已经提前写好了一大堆css和js,我们只需要引入之后按照人家规定好的操作方式即可使用所有的样式和功能。 Bootstrap下载官网地址:https://v3.bootcs......
  • 进入python的世界_day47_前端——JQ补充、bootstrap前端框架
    一、jQuery补充​ 说在最前面,如果想把JQ对象赋值给一个变量名,起名字依旧要讲究,建议名字前加$,这样别人一看就知道是JQ对象1.筛选器//1.属性选择器$('username')//......
  • Spring Cloud之统一配置中心Config初体验
    对于配置的重要性懂的都懂。在普通的单体应用中通常使用配置文件管理应用的所有配置(*.yml/*.properties),但随着微服务数量会在产品中不断增加,考虑系统的可伸缩性和可......
  • 前端开发 6 jQuery使用与Bootstrap
    今日内容详细目录今日内容详细jQuery查找标签1.基本选择器2.组合选择器3.层级选择器4.属性选择器5.基本筛选器6.表单筛选器7.筛选器方法操作标签jQuery事件事件相关补充jQ......
  • jQuery与Bootstrap
    今日内容概要jQuery查找标签jQuery节点操作jQuery事件绑定Bootstrap页面框架今日内容详细jQuery查找标签1.基本选择器 $('#d1') id选择器 $('.c1') class......
  • 前端框架 —— bootstrap介绍
    前端框架——bootstrap介绍bootstrap安装我们可以通过官网下载bootstrap的代码到本地,也可以通过CDN分发网络引入我们的html文件。下载到本地下载Bootstrap生产文件......