在上一篇文章的结尾处我们简单的说了一下PropertiesConfigurationFactory中的bindPropertiesToTarget这个方法的内容,在这个方法中有这样的一段代码:
首先先看一下我们在这个地方进行debug所看到的现象:
这里的names是SpringBoot根据我们在ConfigurationProperties中设置的prefix的值和属性的值所能兼容的配置项的key,这里一共有98种key存在。
上图中的是我们在ConfigurationProperties中设置的prefix所能匹配到的值的情况。我们进入到getPropertySourcesPropertyValues这个方法中看一下这个方法的内容:
1)处的代码如下: 这里主要做的是获取配置项key的匹配器
2)处的代码是我们要分析的一个重点,我们进入到PropertySourcesPropertyValues这个类的构造方法中看一下:
这里给出一个propertySources的debug截图信息:
注意看黑框中的内容,看看黑框中的顺序你会有什么发现呢?在上面的代码中我们可以发现,这里会循环propertySources中的PropertySource来进行处理。
processPropertySource的内容如下:
我们直接进入到processEnumerablePropertySource中看一下:
如果你从上面看到现在的话,那么在这里是不是会有一个疑问呢?因为这里是循环propertySources来获取配置项的值的,如果这样的话,那么后面的propertySources中的值岂不是会覆盖前面的propertySources中的值吗?但是我们看到的现象却又不是这样的,这又是怎么一回事呢?秘密就在getEnumerableProperty中。
所以到这里我们可以看明白为什么优先级高的配置项会最终生效的原因。以上代码简化之后就是这样的:
在processEnumerablePropertySource中还有一个这样的方法:
真正的属性值的设置的动作是在org.springframework.boot.bind.PropertiesConfigurationFactory#doBindPropertiesToTarget这个方法中的这句话中完成的: