Springboot 加载配置文件源码分析
本文的分析是基于springboot 2.2.0.RELEASE。
springboot加载配置文件如application.yml是通过org.springframework.boot.context.config.ConfigFileApplicationListener这个类来完成的。这个类的加载也是通过spring.factories文件中来加载的。
ConfigFileApplicationListener这个类同时实现了EnvironmentPostProcessor、ApplicationListener这两个接口。
EnvironmentPostProcessor接口需要实现的postProcessEnvironment方法,这个方法主要就是用来对Environment来进行增强处理的。而Environment主要是用来表示当前应用程序运行环境的接口。在我们这里来说读取的配置文件最终也会放到这里面来。
简单的调用关系就是下面的图来,具体是怎么调到onApplicationEvent的,比较简单,就不和大家一起看了。直接看本次的重点吧。
下面的方法都是ConfigFileApplicationListener这个类中
在addPropertySources中首先会添加一个用来处理生成随机数的RandomValuePropertySource,然后就会通过内部类Loader来加载配置文件。所以我们本次的主要是看Loader类的load方法的执行流程
下面我们来具体看看load方法的执行流程
void load() { //配置文件的加载就是通过这里来完成的。 //DEFAULT_PROPERTIES = "defaultProperties"; //LOAD_FILTERED_PROPERTY是一个set<String>,里面有两个元素{"spring.profiles.active","spring.profiles.include"} FilteredPropertySource.apply(this.environment, DEFAULT_PROPERTIES, LOAD_FILTERED_PROPERTY, //下面这里是一个lambda表达式,这里暂时省略,后面具体调用到这里我们再具体看。 对于新手小白想更轻松的学好Java提升,Java架构,web开发、大数据,数据分析,人工智能等技术,这里给大家分享系统教学资源,扩列下我尉(同英):1253431195【教程/工具/方法/解疑】
(defaultProperties) -> { ...... }); }
上面的会调用到FilteredPropertySource的静态方法,这个也比较简单,就几行代码。最终又会调用到上面我们的省略的lambda表达式
static void apply(ConfigurableEnvironment environment, String propertySourceName, Set<String> filteredProperties, Consumer<PropertySource<?>> operation) { //这个是获取到当前程序的运行时环境。主要就是当前系统的环境变量、当前程序的环境变量等等,下面放个图一起看看 MutablePropertySources propertySources = environment.getPropertySources(); //这里是从运行时环境中查找key=defaultProperties的属性值,一般情况下,我们没有配置这个属性,获取到的original就是null,就会走到下面的if分支中,回到我们的lambda表达式中,我们就看这个分支吧 PropertySource<?> original = propertySources.get(propertySourceName); if (original == null) { operation.accept(null); return; } propertySources.replace(propertySourceName, new FilteredPropertySource(original, filteredProperties)); try { operation.accept(original); } finally { propertySources.replace(propertySourceName, original); }}
我们看看上面的MutablePropertySources propertySources = environment.getPropertySources();里面的内容