您当前的位置: 首页 >  面试

阿里二面和面试官争论Spring程序配置优先级

发布时间:2021-05-15 21:01:17 ,浏览量: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实例化时 ConfigurationPropertySourcesPropertySource是在ConfigurationPropertySources#attach中被 new 出来的。

获得MutablePropertySources,把自己加入成为第一 这个attach方法就是在Spring应用程序启动时准备环境的时候调用的。

关注
打赏
1688896170
查看更多评论

暂无认证

  • 0浏览

    0关注

    115984博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.0526s