序
本文次要钻研一下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等