ToB企服应用市场:ToB评测及商务社交产业平台

标题: SpringBoot配置文件读取过程分析 [打印本页]

作者: 来自云龙湖轮廓分明的月亮    时间: 2022-8-28 08:53
标题: SpringBoot配置文件读取过程分析
整体流程分析

SpringBoot的配置文件有两种 ,一种是 properties文件,一种是yml文件。在SpringBoot启动过程中会对这些文件进行解析加载。在SpringBoot启动的过程中,配置文件查找和解析的逻辑在listeners.environmentPrepared(environment)方法中。
  1. void environmentPrepared(ConfigurableEnvironment environment) {
  2.     for (SpringApplicationRunListener listener : this.listeners) {
  3.         listener.environmentPrepared(environment);
  4.     }
  5. }
复制代码
依次遍历监听器管理器的environmentPrepared方法,默认只有一个 EventPublishingRunListener 监听器管理器,代码如下,
  1. @Override
  2. public void environmentPrepared(ConfigurableEnvironment environment) {
  3.     this.initialMulticaster
  4.         .multicastEvent(new ApplicationEnvironmentPreparedEvent(this.application, this.args, environment));
  5. }
复制代码
监听管理器的多播器有中有11个,其中针对配置文件的监听器类为 ConfigFileApplicationListener,会执行该类的 onApplicationEvent方法。代码如下,
  1. @Override
  2. public void onApplicationEvent(ApplicationEvent event) {
  3.     if (event instanceof ApplicationEnvironmentPreparedEvent) {
  4.         // 执行 ApplicationEnvironmentPreparedEvent 事件
  5.         onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event);
  6.     }
  7.     if (event instanceof ApplicationPreparedEvent) {
  8.         onApplicationPreparedEvent(event);
  9.     }
  10. }
复制代码
onApplicationEnvironmentPreparedEvent的逻辑为:先从/META-INF/spring.factories文件中获取实现了EnvironmentPostProcessor接口的环境变量后置处理器集合,再把当前的 ConfigFileApplicationListener 监听器添加到 环境变量后置处理器集合中(ConfigFileApplicationListener实现了EnvironmentPostProcessor接口),然后循环遍历 postProcessEnvironment 方法,并传入 事件的SpringApplication 对象和 环境变量。
  1. private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) {
  2.     List<EnvironmentPostProcessor> postProcessors = loadPostProcessors();
  3.     postProcessors.add(this);
  4.     AnnotationAwareOrderComparator.sort(postProcessors);
  5.     for (EnvironmentPostProcessor postProcessor : postProcessors) {
  6.         postProcessor.postProcessEnvironment(event.getEnvironment(), event.getSpringApplication());
  7.     }
  8. }
复制代码
在ConfigFileApplicationListener 的postProcessEnvironment方法中(其他几个环境变量后置处理器与读取配置文件无关),核心是创建了一个Load对象,并且调用了load()方法。
  1. protected void addPropertySources(ConfigurableEnvironment environment, ResourceLoader resourceLoader) {
  2.     RandomValuePropertySource.addToEnvironment(environment);
  3.     new Loader(environment, resourceLoader).load();
  4. }
复制代码
  1. Loader(ConfigurableEnvironment environment, ResourceLoader resourceLoader) {
  2.     this.environment = environment;
  3.     this.placeholdersResolver = new PropertySourcesPlaceholdersResolver(this.environment);
  4.     this.resourceLoader = (resourceLoader != null) ? resourceLoader : new DefaultResourceLoader();
  5.     //从 /META-INF/spring.factories 中加载 PropertySourceLoader 的实现类
  6.     this.propertySourceLoaders = SpringFactoriesLoader.loadFactories(PropertySourceLoader.class,
  7.                                                                      getClass().getClassLoader());
  8. }
复制代码
从 /META-INF/spring.factories 中加载 PropertySourceLoader 的实现类,在具体解析资源文件的时候用到。具体的实现类如下,
  1. org.springframework.boot.env.PropertySourceLoader=\
  2. org.springframework.boot.env.PropertiesPropertySourceLoader,\
  3. org.springframework.boot.env.YamlPropertySourceLoader
复制代码
  1. void load() {
  2.     FilteredPropertySource.apply(...)
  3. }
复制代码
FilteredPropertySource.apply()方法先判断是否存在以 defaultProperties 为名的 PropertySource 属性对象,如果不存在则执行operation.accept,如果存在则先替换,再执行operation.accept方法。代码如下:
[code]static void apply(ConfigurableEnvironment environment, String propertySourceName, Set filteredProperties,                  Consumer




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4