springboot扩展点之 EnvironmentPostProcessor

一、简介

EnvironmentPostProcessor可以在spring conetxt refreshed之前,添加或者修改环境配置。

EnvironmentPostProcessor 在实现类必须在META-INF/spring.factories中注册

启动顺序控制方式:可以实现 Ordered 接口,或者可以在类上增加@Order注解.

EnvironmentPostProcessor接口实现代表:ConfigFileApplicationListener, 其他实现:CloudFoundryVcapEnvironmentPostProcessorConfigDataEnvironmentPostProcessorDebugAgentEnvironmentPostProcessorDevToolsHomePropertiesPostProcessorDevToolsPropertyDefaultsPostProcessorRandomValuePropertySourceEnvironmentPostProcessorSpringApplicationJsonEnvironmentPostProcessorSystemEnvironmentPropertySourceEnvironmentPostProcessor

使用场景:需要在应用启动前注入环境变量的

二、Environment

Environment是在spring应用中存储运行时的环境变量,提供了一些可以访问环境变量的方法,意味着我们可以动态去注入、修改、读取环境变量。Enviroment变量来自于bootstrap proterties、application properties、系统环境变量、jvm环境变理、servlet context parameters等。

三、实现原理

SpringApplication的run方法中在prepareEnvironment中调用
EventPublishingRunListener 中会调用environmentPrepared方法, 在environmentPrepared方法中会发布事件ApplicationEnvironmentPreparedEvent

EnvironmentPostProcessorApplicationListener监听ApplicationEnvironmentPreparedEvent 事件,当environment prepared后执行自定义的EnvironmentPostProcessor

 四、Example

通过以下示例,将会带大家实现一个Nacos的启动环境注入环境变量,主要目的是将nacos启动配置内置,将配置隔离机制也内置,实现0配置启动应用

4.1 实现自定义的 EnvironmentPostProcessor,在启动时将环境变量注入

​
public class WafNacosEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {

  

    private static final String CONFIG_PREFIX = "spring.cloud.nacos.config.";

  

    private static final String DISCOVERY_PREFIX = "spring.cloud.nacos.discovery.";

  

    private static final String KEY_CONFIG_SERVERADDR = CONFIG_PREFIX + "serverAddr";

  

    private static final String KEY_CONFIG_USERNAME = CONFIG_PREFIX + "username";

  

    private static final String KEY_CONFIG_PASSWORD = CONFIG_PREFIX + "password";

  

    private static final String KEY_CONFIG_GROUP = CONFIG_PREFIX + "group";

  

    private static final String KEY_CONFIG_FILEEXTENSION = CONFIG_PREFIX + "file-extension";

  

    private static final String KEY_DISCOVERY_SERVERADDR = DISCOVERY_PREFIX + "serverAddr";

  

    private static final String KEY_DISCOVERY_USERNAME = DISCOVERY_PREFIX + "username";

  

    private static final String KEY_DISCOVERY_PASSWORD = DISCOVERY_PREFIX + "password";

  

    private static final String KEY_DISCOVERY_NAMESPACE= DISCOVERY_PREFIX + "namespace";

  

    @Override

    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {

        Map<String, Object> map = new HashMap<>();

        Properties envProperties = WafNacosConfig.getNacosConfig(getActiveEnv(environment));

        //nacos config

        addProperties(environment, map, KEY_CONFIG_SERVERADDR,envProperties.getProperty(SERVER_ADDR));

        addProperties(environment, map, KEY_CONFIG_USERNAME,envProperties.getProperty(USERNAME));

        addProperties(environment, map, KEY_CONFIG_PASSWORD,envProperties.getProperty(PASSWORD));

        addProperties(environment, map, KEY_CONFIG_GROUP,getApplicationName(environment));

        addProperties(environment, map, KEY_CONFIG_FILEEXTENSION,"yml");

  

        //nacos discovery

        addProperties(environment, map, KEY_DISCOVERY_SERVERADDR,envProperties.getProperty(SERVER_ADDR));

        addProperties(environment, map, KEY_DISCOVERY_USERNAME,envProperties.getProperty(USERNAME));

        addProperties(environment, map, KEY_DISCOVERY_PASSWORD,envProperties.getProperty(PASSWORD));

        addProperties(environment, map, KEY_DISCOVERY_NAMESPACE,getApplicationName(environment));

  

        if(!map.isEmpty()) {

            environment.getPropertySources().addLast(new MapPropertySource("NacosBootstrap", map));

        }

    }

  

    private void addProperties(ConfigurableEnvironment environment, Map<String, Object> map, String key, String value){

        if(!environment.containsProperty(key)){

            map.put(key, value);

        }

    }

  

  

    @Override

    public int getOrder() {

        return Ordered.LOWEST_PRECEDENCE;

    }

}

​

4.2 在spring.factories中增加启动

org.springframework.boot.env.EnvironmentPostProcessor=\

cn.xxx.nacos.WafNacosEnvironmentPostProcessor

上一篇:etcd集群部署


下一篇:当新的线程类型将运行时,更大的线程池或其他ExecutorService?