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