简易配置中心原理及流程说明

简易配置中心原理及流程说明

  • 说明
    • 原理
      • 源码详解
      • 配置中心思路
    • 简易搭建例子

说明

本篇文档将详细说明简易配置中心原理及流程说明,希望对大家有所帮助

原理

在启动后优先于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端口为例子,由于时间关系,只在代码中模拟获得配置项。

  • 新建配置类PropertiesConfigPostProcessor
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;
    }
}
  • 新建一个/META-INF/spring.factories文件,内容为
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
}

以上就是简易流程,懂得原理,可自行扩展!

你可能感兴趣的:(java,spring源码解析,config,spring)