本文次要钻研一下springboot的EnvironmentPostProcessor

EnvironmentPostProcessor

org/springframework/boot/env/EnvironmentPostProcessor.java

@FunctionalInterfacepublic interface EnvironmentPostProcessor {    /**     * Post-process the given {@code environment}.     * @param environment the environment to post-process     * @param application the application to which the environment belongs     */    void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application);}
springboot提供了EnvironmentPostProcessor接口,该接口有postProcessEnvironment办法,其中envrionment参数类型为ConfigurableEnvironment,即利用能够通过实现这个接口进行env环境变量的操作

EnvironmentPostProcessorApplicationListener

org/springframework/boot/env/EnvironmentPostProcessorApplicationListener.java

/** * {@link SmartApplicationListener} used to trigger {@link EnvironmentPostProcessor * EnvironmentPostProcessors} registered in the {@code spring.factories} file. * * @author Phillip Webb * @since 2.4.0 */public class EnvironmentPostProcessorApplicationListener implements SmartApplicationListener, Ordered {    /**     * The default order for the processor.     */    public static final int DEFAULT_ORDER = Ordered.HIGHEST_PRECEDENCE + 10;    private final DeferredLogs deferredLogs;    private int order = DEFAULT_ORDER;    private final EnvironmentPostProcessorsFactory postProcessorsFactory;    /**     * Create a new {@link EnvironmentPostProcessorApplicationListener} with     * {@link EnvironmentPostProcessor} classes loaded via {@code spring.factories}.     */    public EnvironmentPostProcessorApplicationListener() {        this(EnvironmentPostProcessorsFactory                .fromSpringFactories(EnvironmentPostProcessorApplicationListener.class.getClassLoader()));    }    /**     * Create a new {@link EnvironmentPostProcessorApplicationListener} with post     * processors created by the given factory.     * @param postProcessorsFactory the post processors factory     */    public EnvironmentPostProcessorApplicationListener(EnvironmentPostProcessorsFactory postProcessorsFactory) {        this(postProcessorsFactory, new DeferredLogs());    }    EnvironmentPostProcessorApplicationListener(EnvironmentPostProcessorsFactory postProcessorsFactory,            DeferredLogs deferredLogs) {        this.postProcessorsFactory = postProcessorsFactory;        this.deferredLogs = deferredLogs;    }    @Override    public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {        return ApplicationEnvironmentPreparedEvent.class.isAssignableFrom(eventType)                || ApplicationPreparedEvent.class.isAssignableFrom(eventType)                || ApplicationFailedEvent.class.isAssignableFrom(eventType);    }    @Override    public void onApplicationEvent(ApplicationEvent event) {        if (event instanceof ApplicationEnvironmentPreparedEvent) {            onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event);        }        if (event instanceof ApplicationPreparedEvent) {            onApplicationPreparedEvent((ApplicationPreparedEvent) event);        }        if (event instanceof ApplicationFailedEvent) {            onApplicationFailedEvent((ApplicationFailedEvent) event);        }    }    private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) {        ConfigurableEnvironment environment = event.getEnvironment();        SpringApplication application = event.getSpringApplication();        for (EnvironmentPostProcessor postProcessor : getEnvironmentPostProcessors(event.getBootstrapContext())) {            postProcessor.postProcessEnvironment(environment, application);        }    }    private void onApplicationPreparedEvent(ApplicationPreparedEvent event) {        finish();    }    private void onApplicationFailedEvent(ApplicationFailedEvent event) {        finish();    }    private void finish() {        this.deferredLogs.switchOverAll();    }    List<EnvironmentPostProcessor> getEnvironmentPostProcessors(ConfigurableBootstrapContext bootstrapContext) {        return this.postProcessorsFactory.getEnvironmentPostProcessors(this.deferredLogs, bootstrapContext);    }    @Override    public int getOrder() {        return this.order;    }    public void setOrder(int order) {        this.order = order;    }}
EnvironmentPostProcessorApplicationListener用于在接管到ApplicationEnvironmentPreparedEvent事件时触发执行EnvironmentPostProcessor的postProcessEnvironment办法
# Application Listenersorg.springframework.context.ApplicationListener=\org.springframework.boot.ClearCachesApplicationListener,\org.springframework.boot.builder.ParentContextCloserApplicationListener,\org.springframework.boot.context.FileEncodingApplicationListener,\org.springframework.boot.context.config.AnsiOutputApplicationListener,\org.springframework.boot.context.config.DelegatingApplicationListener,\org.springframework.boot.context.logging.LoggingApplicationListener,\org.springframework.boot.env.EnvironmentPostProcessorApplicationListener,\org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener

示例

public class EnvironmentPostProcessorExample implements EnvironmentPostProcessor {    private final YamlPropertySourceLoader loader = new YamlPropertySourceLoader();    @Override    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {        Resource path = new ClassPathResource("com/example/myapp/config.yml");        PropertySource<?> propertySource = loadYaml(path);        environment.getPropertySources().addLast(propertySource);    }    private PropertySource<?> loadYaml(Resource path) {        if (!path.exists()) {            throw new IllegalArgumentException("Resource " + path + " does not exist");        }        try {            return this.loader.load("custom-resource", path).get(0);        }        catch (IOException ex) {            throw new IllegalStateException("Failed to load yaml configuration from " + path, ex);        }    }}
EnvironmentPostProcessorExample实现了postProcessEnvironment办法,它额定加载com/example/myapp/config.yml外头的配置最为最初的propertySource

小结

springboot的EnvironmentPostProcessor提供了一个environment的扩大接口,不便利用去做environment的扩大,比方扩大propertySource等