本文主要通过两种不同的方式往Environment
中添加自定义的参数,在《spring boot参数配置之Environment源码分析》一文中讲过,spring boot填充Environment
参数主要在ConfigFileApplicationListener
的onApplicationEnvironmentPreparedEvent
方法
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());
}
}
这里的postProcessors
包含以下6个postProcessors
,分别以6种不同的方法来加载不同场景下的参数配置:
其中CustEnvironmentPostProcessor
是我自定义的。
通常采用以下两种常用的方式来添加自定义参数到Environment中
一、借助ConfigFileApplicationListener,在指定的配置文件添加参数
ConfigFileApplicationListener
实现了EnvironmentPostProcessor
,该类会从classpath:/,classpath:/config/,file:./,file:./config/ 目录下的 application.properties、application.yml文件读取参数,如果在不同的目录中存在多个配置文件,它的读取顺序是:
1、config/application.properties(项目根目录中config目录下)
2、config/application.yml
3、application.properties(项目根目录下)
4、application.yml
5、resources/config/application.properties(项目resources目录中config目录下)
6、resources/config/application.yml
7、resources/application.properties(项目的resources目录下)
8、resources/application.yml
因此我们可以往以上文件中新增自定义的参数,这种方式可以满足大部分需求。
二、自定义类实现EnvironmentPostProcessor接口
第一种方式有些局限性,如果应用需要从自己的配置中心去获取数据,第一种方式就无法实现,通过onApplicationEnvironmentPreparedEvent
方式可以知道spring boot会执行所有实现EnvironmentPostProcessor
的类的postProcessEnvironment
方法,我们自定义CustEnvironmentPostProcessor
类实现EnvironmentPostProcessor
接口,如下:
public class CustEnvironmentPostProcessor implements EnvironmentPostProcessor{
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
Map<String, Object> source = new HashMap<>();
source.put("configCenter.zookeeper.address","192.168.100.100:2181");
source.put("configCenter.redis.address","192.168.100.100:6379");
MapPropertySource propertiesPropertySource = new MapPropertySource("configCenter",source);
environment.getPropertySources().addLast(propertiesPropertySource);
}
}
EnvironmentPostProcessor
的子类都采用的是SpringFactoriesLoader
来加载的,所以我们自定义的CustEnvironmentPostProcessor
类名上无须添加@Component
或@Service
注解,源代码如下:
List<EnvironmentPostProcessor> loadPostProcessors() {
return SpringFactoriesLoader.loadFactories(EnvironmentPostProcessor.class,
getClass().getClassLoader());
}