当前位置: 首页> 财经> 创投人物 > Spring Boot-加载配置文件ConfigDataEnvironmentPostProcessor

Spring Boot-加载配置文件ConfigDataEnvironmentPostProcessor

时间:2025/7/13 18:30:50来源:https://blog.csdn.net/tales522/article/details/141367441 浏览次数:0次

org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor是 Spring Boot 中的一个关键组件,它负责处理配置数据(config data),并将其应用于 Spring 应用上下文中。下面我们详细解读这个类的产生背景、作用和工作原理。

产生背景

在 Spring Boot 中,配置数据是指来自各种外部来源(如 YAML 文件、properties 文件、环境变量、命令行参数等)的配置信息。Spring Boot 提供了一种机制来自动读取这些配置信息,并将它们绑定到应用中的 Bean 上。为了更好地管理和处理这些配置数据,Spring Boot 引入了配置数据功能,其中包括 `ConfigData` 和 `ConfigDataLocation` 等概念。

作用

`ConfigDataEnvironmentPostProcessor` 的主要作用是处理配置数据,并将这些数据合并到应用的环境配置中。具体来说,它执行以下几个关键任务:

1. 加载配置数据:从不同的配置源(如文件系统、类路径、云配置中心等)加载配置数据。
2. 解析配置数据:解析加载的配置数据,并将其转换为 Spring 可以理解的格式。
3. 合并配置数据:将解析后的配置数据合并到 `ConfigurableEnvironment` 中。
4. 处理占位符:解析配置数据中的占位符,并将其替换为实际的值。

工作原理

`ConfigDataEnvironmentPostProcessor` 的工作原理涉及以下几个步骤:

1. 实例化:在 Spring 应用启动时,`ConfigDataEnvironmentPostProcessor` 会作为 `BeanFactoryPostProcessor` 的一部分被实例化。
2. 配置数据定位:通过 `ConfigDataLocationResolver` 来确定配置数据的位置。
3. 加载配置数据:使用 `ConfigDataLoader` 来加载配置数据。
4. 解析配置数据:使用 `ConfigDataParser` 来解析加载的数据。
5. 合并配置数据:将解析后的配置数据合并到 `ConfigurableEnvironment` 中。
6. 处理占位符:在合并过程中处理配置数据中的占位符。

源码流程:

这个类有个成员变量postProcessorsFactory,是个函数,函数签名是接受ClassLoader类型参数,返回EnvironmentPostProcessorsFactory类型参数。这个类的无参构造是在SpringApplication实例化时被调用的。这里主要是要理解、熟悉函数作为参数传递的用法。这个函数实际传的值是org.springframework.boot.env.EnvironmentPostProcessorsFactory#fromSpringFactories(),

下面就是执行监听器回调,最后调用了this.postProcessorsFactory.apply(classLoader);来得到一个EnvironmentPostProcessorsFactory类型实例,其实际类型其实是ReflectionEnvironmentPostProcessorsFactory

public class EnvironmentPostProcessorApplicationListener implements SmartApplicationListener, Ordered {private final Function<ClassLoader, EnvironmentPostProcessorsFactory> postProcessorsFactory;/*** Create a new {@link EnvironmentPostProcessorApplicationListener} with* {@link EnvironmentPostProcessor} classes loaded through {@code spring.factories}.*/public EnvironmentPostProcessorApplicationListener() {this(EnvironmentPostProcessorsFactory::fromSpringFactories, new DeferredLogs());}EnvironmentPostProcessorApplicationListener(Function<ClassLoader, EnvironmentPostProcessorsFactory> postProcessorsFactory, DeferredLogs deferredLogs) {this.postProcessorsFactory = postProcessorsFactory;this.deferredLogs = deferredLogs;}@Overridepublic void onApplicationEvent(ApplicationEvent event) {if (event instanceof ApplicationEnvironmentPreparedEvent) {onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event);}if (event instanceof ApplicationPreparedEvent) {onApplicationPreparedEvent();}if (event instanceof ApplicationFailedEvent) {onApplicationFailedEvent();}}private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) {ConfigurableEnvironment environment = event.getEnvironment();SpringApplication application = event.getSpringApplication();for (EnvironmentPostProcessor postProcessor : getEnvironmentPostProcessors(application.getResourceLoader(),event.getBootstrapContext())) {postProcessor.postProcessEnvironment(environment, application);}}List<EnvironmentPostProcessor> getEnvironmentPostProcessors(ResourceLoader resourceLoader,ConfigurableBootstrapContext bootstrapContext) {ClassLoader classLoader = (resourceLoader != null) ? resourceLoader.getClassLoader() : null;EnvironmentPostProcessorsFactory postProcessorsFactory = this.postProcessorsFactory.apply(classLoader);return postProcessorsFactory.getEnvironmentPostProcessors(this.deferredLogs, bootstrapContext);}
}

还是读取spring.factories文件得到 EnvironmentPostProcessor用于可扩展的设计。

这个类的方法不好理解,这里用了Instantiator,构建Instantiator时第二个参数是一个方法,告诉Instantiator,在创建EnvironmentPostProcessor实例的时候,如果构造函数或setter方法中有DeferredLogFactory类型的参数,则使用logFactory作为实际值,下面几个add作用也是一样。

class ReflectionEnvironmentPostProcessorsFactory implements EnvironmentPostProcessorsFactory {@Overridepublic List<EnvironmentPostProcessor> getEnvironmentPostProcessors(DeferredLogFactory logFactory,ConfigurableBootstrapContext bootstrapContext) {Instantiator<EnvironmentPostProcessor> instantiator = new Instantiator<>(EnvironmentPostProcessor.class,(parameters) -> {parameters.add(DeferredLogFactory.class, logFactory);parameters.add(Log.class, logFactory::getLog);parameters.add(ConfigurableBootstrapContext.class, bootstrapContext);parameters.add(BootstrapContext.class, bootstrapContext);parameters.add(BootstrapRegistry.class, bootstrapContext);});return (this.classes != null) ? instantiator.instantiateTypes(this.classes): instantiator.instantiate(this.classLoader, this.classNames);}}

org.springframework.boot.context.config.ConfigDataEnvironment#processAndApply

关键字:Spring Boot-加载配置文件ConfigDataEnvironmentPostProcessor

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: