在前面的文章基础上
https://blog.csdn.net/zlpzlpzyd/article/details/136065211
加载完文件转换为 Environment 中对应的值之后,接下来需要将对应的值与对应的配置类进行绑定,方便对应的组件取值处理接下来的操作。
对应的配置值与配置类绑定通过 ConfigurationPropertiesBindingPostProcessor 来处理。
首先调用 ApplicationContextAware#setApplicationContext() 将 ApplicationContext 对象向当前类赋值。
然后利用上面的 ApplicationContext 调用 InitializingBean#afterPropertiesSet() 进行 BeanDefinitionRegistry 和 ConfigurationPropertiesBinder 获取。
最后调用 BeanPostProcessor#postProcessBeforeInitialization() 进行前置处理,调用 ConfigurationPropertiesBinder 中的方法处理后面的绑定值逻辑。
获取 Binder 对象进行绑值处理
通过 findProperty() 找到对应的属性,对应值不为空返回
调用 SpringConfigurationPropertySources 的迭代器将 Environment 中的值复制到变量 cache 中。
遍历时生成 SpringConfigurationPropertySources$SourcesIterator,将 sources 中的值传递到 SourcesIterator 的 iterators 变量中。
首次迭代为 environmentProperties,对应接口 ConfigurableEnvironment 的实现类 StandardServletEnvironment。
遍历变量 sources 中的元素 environmentProperties 的迭代器中的数据
0 = {ConfigurationPropertySourcesPropertySource@4977} "ConfigurationPropertySourcesPropertySource {name='configurationProperties'}"
1 = {PropertySource$StubPropertySource@4978} "StubPropertySource {name='servletConfigInitParams'}"
2 = {PropertySource$StubPropertySource@4979} "StubPropertySource {name='servletContextInitParams'}"
3 = {PropertiesPropertySource@4886} "PropertiesPropertySource {name='systemProperties'}"
4 = {SystemEnvironmentPropertySourceEnvironmentPostProcessor$OriginAwareSystemEnvironmentPropertySource@4882} "OriginAwareSystemEnvironmentPropertySource {name='systemEnvironment'}"
5 = {RandomValuePropertySource@4880} "RandomValuePropertySource {name='random'}"
6 = {MapPropertySource@4892} "MapPropertySource {name='springCloudClientHostInfo'}"
7 = {OriginTrackedMapPropertySource@4890} "OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/application.yml]'}"
8 = {OriginTrackedMapPropertySource@4888} "OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/bootstrap.yml]'}"
9 = {MapPropertySource@4894} "MapPropertySource {name='springCloudDefaultProperties'}"
10 = {CachedRandomPropertySource@4896} "CachedRandomPropertySource {name='cachedrandom'}"
cache 中的数据
{RandomValuePropertySource@4994} "RandomValuePropertySource {name='random'}" -> {SpringConfigurationPropertySource@4995} "RandomValuePropertySource {name='random'}"
{SystemEnvironmentPropertySourceEnvironmentPostProcessor$OriginAwareSystemEnvironmentPropertySource@4996} "OriginAwareSystemEnvironmentPropertySource {name='systemEnvironment'}" -> {SpringIterableConfigurationPropertySource@4997} "OriginAwareSystemEnvironmentPropertySource {name='systemEnvironment'}"
{PropertiesPropertySource@4998} "PropertiesPropertySource {name='localProperties'}" -> {SpringIterableConfigurationPropertySource@4999} "PropertiesPropertySource {name='localProperties'}"
{PropertiesPropertySource@5000} "PropertiesPropertySource {name='systemProperties'}" -> {SpringIterableConfigurationPropertySource@5001} "PropertiesPropertySource {name='systemProperties'}"
{OriginTrackedMapPropertySource@5002} "OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/bootstrap.yml]'}" -> {SpringIterableConfigurationPropertySource@5003} "OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/bootstrap.yml]'}"
{OriginTrackedMapPropertySource@5004} "OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/application.yml]'}" -> {SpringIterableConfigurationPropertySource@5005} "OriginTrackedMapPropertySource {name='applicationConfig: [classpath:/application.yml]'}"
{MapPropertySource@5006} "MapPropertySource {name='springCloudClientHostInfo'}" -> {SpringIterableConfigurationPropertySource@5007} "MapPropertySource {name='springCloudClientHostInfo'}"
{MapPropertySource@5008} "MapPropertySource {name='springCloudDefaultProperties'}" -> {SpringIterableConfigurationPropertySource@5009} "MapPropertySource {name='springCloudDefaultProperties'}"
{CachedRandomPropertySource@5010} "CachedRandomPropertySource {name='cachedrandom'}" -> {SpringConfigurationPropertySource@5011} "CachedRandomPropertySource {name='cachedrandom'}"
以迭代器中的值顺序为准与 cache 中进行比对,返回对应的配置类,然后再将对应的配置属性从对应的配置文件中获取。
可以发现,对应配置值顺序如下
如果 jvm 虚拟机参数中未指定,获取环境变量中的值
如果环境变量中未指定,获取 application 配置文件中的值
如果 application 配置文件中未指定,获取 bootstrap 配置文件中的值
如果 bootstrap 配置文件中未指定,获取外部配置文件中的值
这样参数的顺序正好对应起来最后匹配 bootstrap 值的问题,例如项目中使用了 nacos 中的配置中心功能,很多参数不需要在项目中进行配置,在 nacos 中进行指定就可以,但是 nacos 中的配置参数与项目是隔离的。
调用 DataObjectBinder 的实现类 JavaBeanBinder 将变量值设置到对应的配置类中
可以发现,最终赋值操作通过反射处理。