序
本文主要研究一下springboot的EnvironmentPostProcessor
EnvironmentPostProcessor
org/springframework/boot/env/EnvironmentPostProcessor.java
代码语言:javascript复制@FunctionalInterface
public 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
代码语言:javascript复制/**
* {@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;
}
}
代码语言:javascript复制EnvironmentPostProcessorApplicationListener用于在接收到ApplicationEnvironmentPreparedEvent事件时触发执行EnvironmentPostProcessor的postProcessEnvironment方法
# Application Listeners
org.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
示例
代码语言:javascript复制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等