0 前言
一般用application.yml
实现Spring Boot应用参数配置。但Spring配置有优先级,避免重复配置项的覆盖,须清晰优先级。
Spring通过Environment抽象出:
- Profile:规定场景。定义诸如dev、test、prod等环境
- Property:PropertySources,各种配置源。一个环境中可能有多个配置源,每个配置源有许多配置项。查询配置信息时,按配置源优先级进行查询
Property是如何查询配置的?
首先看下配置的优先级:
env.getPropertySources().stream()
.forEach(System.out::println);
如下共九个配置源:
- systemProperties
系统配置 -
applicationConfig
配置文件,我们的 yml 文件配置。如 application.yml 和 bootstrap.yml,首先加载bootstrap.yml。
其中的OriginAwareSystemEnvironmentPropertySource就是我们的application.yml
。
StandardEnvironment,继承自
AbstractEnvironment
- MutablePropertySources#propertySources
所有的配置源 -
getProperty
通过PropertySourcesPropertyResolver类进行查询配置
-
实例化PropertySourcesPropertyResolver时,传入了当前的MutablePropertySources
那就来具体看看该类:
MutablePropertySources
PropertySourcesPropertyResolver
构造器传入后面用来遍历的propertySources。
结合AbstractEnvironment,这个propertySources就是AbstractEnvironment#MutablePropertySources。
遍历时,若发现配置源中有对应K的V,则使用该V。
所以MutablePropertySources中的配置源顺序很关键。
- 真正查询配置的方法
在查询所有配置源时,NO.1的 ConfigurationPropertySourcesPropertySource并非一个实际存在的配置源,而是一个代理。debug 下查看到"user.name"的值是由它提供并返回,且没有再遍历后面的PropertySource看看有无"user.name"
ConfigurationPropertySourcesPropertySource
-
getProperty()最终还调用findConfigurationProperty查询对应配置
-
上图中getSource()结果就是SpringConfigurationPropertySources
-
其中包含的配置源列表
第一个就是ConfigurationPropertySourcesPropertySource,这遍历不会导致死循环吗?
注意到configurationProperty的实际配置是从系统属性来的。
SpringConfigurationPropertySources
ConfigurationPropertySourcesPropertySource是所有配置源的NO.1,其早就知道了PropertySourcesPropertyResolver的遍历逻辑。
那知道遍历逻辑后,如何暗箱操作可以让自己成为南波湾配置源?
ConfigurationPropertySourcesPropertySource实例化时
获得MutablePropertySources,把自己加入成为第一
这个attach方法就是在Spring应用程序启动时准备环境的时候调用的。
本文已收录在Github,关注我,紧跟本系列专栏文章,咱们下篇再续!
作者简介:魔都架构师,多家大厂后端一线研发经验,在分布式系统设计、数据平台架构和AI应用开发等领域都有丰富实践经验。
各大技术社区头部专家博主。具有丰富的引领团队经验,深厚业务架构和解决方案的积累。
负责:
- 中央/分销预订系统性能优化
- 活动&券等营销中台建设
- 交易平台及数据中台等架构和开发设计
- 车联网核心平台-物联网连接平台、大数据平台架构设计及优化
- LLM Agent应用开发
- 区块链应用开发
- 大数据开发挖掘经验
- 推荐系统项目
目前主攻市级软件项目设计、构建服务全社会的应用系统。
参考:
本文由博客一文多发平台 OpenWrite 发布!