本篇文档将详细说明简易配置中心原理及流程说明,希望对大家有所帮助
在启动后优先于spring默认配置扫描器增加所需配置项,spring将读取第一个值使之生效。
对spring有了解的朋友都知道,spring对于默认组件或一些配置都是写在META-INF文件夹下的spring.factories文件中,spring默认配置项也是配置在此。
在spring-boot-1.5.9.RELEASE.jar!/META-INF/spring.factories文件中,有一项与配置相关的配置
# Application Listeners 监听
org.springframework.context.ApplicationListener=\
org.springframework.boot.context.config.ConfigFileApplicationListener
# Environment Post Processors 环境处理
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor
此监听类为配置文件关键类。
public class ConfigFileApplicationListener implements EnvironmentPostProcessor, SmartApplicationListener, Ordered {}
可以看到,此监听实现了EnvironmentPostProcessor,SmartApplicationListener与Ordered。
// 监听回调函数
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ApplicationEnvironmentPreparedEvent) {
//在此初始化配置项
onApplicationEnvironmentPreparedEvent(
(ApplicationEnvironmentPreparedEvent) event);
}
if (event instanceof ApplicationPreparedEvent) {
onApplicationPreparedEvent(event);
}
}
//配置文件初始化读取
private void onApplicationEnvironmentPreparedEvent(
ApplicationEnvironmentPreparedEvent event) {
//加载所有EnvironmentPostProcessor类型bean,此时扫描还未开始,获取到的都必须是上面说的spring.factories中配置的Environment Post Processors。
List postProcessors = loadPostProcessors();
//增加自己
postProcessors.add(this);
//排序
AnnotationAwareOrderComparator.sort(postProcessors);
for (EnvironmentPostProcessor postProcessor : postProcessors) {
//执行
postProcessor.postProcessEnvironment(event.getEnvironment(),
event.getSpringApplication());
}
}
//加载application.yml及指定profile文件
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment,
SpringApplication application) {
//加载
addPropertySources(environment, application.getResourceLoader());
configureIgnoreBeanInfo(environment);
bindToSpringApplication(environment, application);
}
加载流程及优先级清楚了,那么可以开始动手了~
由于执行到这步的时候,还未开始扫描,所以使用注解是无效的。那么新建一个/META-INF/spring.factories文件,并增加相应配置,在ConfigFileApplicationListener之前执行即可。
老规矩,不会写详细的步骤,更希望大家能明白原理,举一反三哟
以修改tomcat端口为例子,由于时间关系,只在代码中模拟获得配置项。
public class PropertiesConfigPostProcessor implements EnvironmentPostProcessor, Ordered {
//优先于ConfigFileApplicationListener
public static final int DEFAULT_ORDER = Ordered.HIGHEST_PRECEDENCE + 9;
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
//此时PropertySources中无application配置项,我们新增一个server.port为8999的配置。此步骤如为真实配置中心则可自行获得。
environment.getPropertySources().addLast(new MapPropertySource("configServerInitProperties", new QuickHashMap().quickPut("server.port", 8999)));
}
@Override
public int getOrder() {
return DEFAULT_ORDER;
}
}
org.springframework.boot.env.EnvironmentPostProcessor=\
top.wboost.example.PropertiesConfigPostProcessor
-application.yml配置
server:
port: 8000
启动后,日志显示端口为8999.
我们查看系统中存在的配置项为如下所示(省略其他配置项)
{
"data": {
"applicationConfigurationProperties": {
"server.port,class org.springframework.boot.context.config.ConfigFileApplicationListener$ConfigurationPropertySources": 8000
},
"configServerInitProperties,class org.springframework.core.env.MapPropertySource": {
"server.port": 8999
}
},
"info": {
"code": 10906,
"message": "执行成功",
"systemCode": "DO_OK"
},
"status": 0
}
以上就是简易流程,懂得原理,可自行扩展!