Config使用
Config本地配置文件加载原理分析
Config配置中心配置加载原理分析
本文主要内容:
- 了解bootstrap Content如何读取bootstrap.properties配置文件
- 了解bootstrap Content如何读取Config Service配置中心的参数信息
- Config Service配置中心如何响应客户端的请求
在<Config本地配置文件加载原理分析 >中分析到:当我们集成了SpringCloud组件到项目中,SpringBoot启动时,会通过BootstrapApplicationListener初始化了一个名为bootstrap的容器作为parent context,并对该容器做出以下设置
:
- 指定加载的配置文件为:bootstrap.properties/yaml
- 创建一个名字bootstrap的PropertySource,并将它设置在所有PropertySources的第一位
- 设置List
- 启动bootstrap context容器
下面是bootstrap context容器的创建,以及启动后加载本地配置文件和配置中心配置的简易流程图,可以对照着看源码分析
一、客户端读取本地配置
1.1、通过ConfigFileApplicationListener加载本地配置文件
ConfigFileApplicationListener会读取我们指定的配置文件bootstrap.properties,具体实现请自行看源码
1.ConfigFileApplicationListener默认是读取的配置文件application.properties/yaml
2.BootstrapApplicationListener在创建bootstrap context时,将配置文件名称指定为bootstrap,所以此时的ConfigFileApplicationListener会读取配置文件bootstrap.properties/yaml
1.2、BootstrapApplicationListener会跳过执行
bootstrap context中也会存在一个BootstrapApplicationListener,但是因为PropertySources中已经存在了bootstrap,所以会直接返回,不执行后续逻辑
二、客户端读取Config Service配置中心里的参数
2.1、ApplicationContextInitializer的调用
SpringApplication.run()方法在刷新容器之前,会先执行prepareContext()方法:逐一调用所有ApplicationContextInitializer实现类的initialize()方法
方法调用链如下:
- SpringApplication.run()
- ->prepareContext()
- ->applyInitializers()
- ->ApplicationContextInitializer.initialize()
SpringApplication.applyInitializers()方法源码:
protected void applyInitializers(ConfigurableApplicationContext context) {
for (ApplicationContextInitializer initializer : getInitializers()) {
Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(),
ApplicationContextInitializer.class);
Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");
initializer.initialize(context);
}
}
在ApplicationContextInitializer所有实现类中,有一个Spring Cloud定义的实现类:PropertySourceBootstrapConfiguration
2.2、PropertySourceBootstrapConfiguration源码分析
2.2.1、PropertySourceBootstrapConfiguration.initialize()方法分析
PropertySourceBootstrapConfiguration通过PropertySourceLocator的实现类,完成配置加载
- 逐一调用:List< PropertySourceLocator>的locateCollection()方法
- 保存PropertySourceLocator读取到的PropertySource
PropertySourceBootstrapConfiguration.initialize()方法源码
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
List<PropertySource<?>> composite = new ArrayList<>();
AnnotationAwareOrderComparator.sort(this.propertySourceLocators);
boolean empty = true;
ConfigurableEnvironment environment = applicationContext.getEnvironment();
// 循环调用PropertySourceLocator.locateCollection(environment)方法
for (PropertySourceLocator locator : this.propertySourceLocators) {
// 默认情况只有一个实现类ConfigServicePropertySourceLocator,它实现了读取远程配置中心配置参数
Collection<PropertySource<?>> source = locator.locateCollection(environment);
if (source == null || source.size() == 0) {
continue;
}
List<PropertySource<?>> sourceList = new ArrayList<>();
for (PropertySource<?> p : source) {
sourceList.add(new BootstrapPropertySource<>(p));
}
logger.info("Located property source: " + sourceList);
composite.addAll(sourceList);
empty = fa