EnvironmentPostProcessor
是Spring Boot提供的一个后置处理器,用于处理Spring应用的ConfigurableEnvironment
对象,如添加默认值。
EnvironmentPostProcessor
是一个函数接口,定义如下:
package org.springframework.boot.env;
@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);
}
本文以修改Spring Boot应用的默认服务端口为例,示例如何使用EnvironmentPostProcessor
对Spring Boot的环境变量进行修改。
在默认情况下,Spring Boot应用的默认服务端口为8080
, 也可以通过server.port
进行修改,但是这种修改仅对当前项目起作用, 如何对某个公司或组织下的所有项目进行默认的服务商品进行修改呢?
首先,自定义一个实现了EnvironmentPostProcessor
类,如修改默认端口,通常情况下,
public class ServerEnvironmentPostProcessor implements EnvironmentPostProcessor {
public static final String SERVER_PORT_PROPERTY_NAME = "server.port";
@Override
public void postProcessEnvironment(final ConfigurableEnvironment environment, final SpringApplication application) {
environment.getPropertySources()
.addLast(new MapPropertySource("defaultServerProperties",
Collections.singletonMap(SERVER_PORT_PROPERTY_NAME, 80)));
}
}
上述代码相当于在
application
配置文件中声明了如下配置:server.port=80
然后,在classpath:/META-INF/spring.factories
文件中添加如下配置:
# EnvironmentPostProcessor
org.springframework.boot.env.EnvironmentPostProcessor=\
org.ifinalframework.boot.env.ServerEnvironmentPostProcessor
启动Spring应用,服务将运行在80端口。
上述实现,仅在未显示指定
server.port
的情况下有效,这是因为此处使用的是addLast()
进行的配置,如果想忽略显示指定的配置,可使用addFirst()
方式注入。
从Spring Boot 2.4.0
开始,引入了EnvironmentPostProcessorApplicationListener
应用监听器。
该接口实现了SmartApplicationListener
,并重写了supportsEventType(Class)
方法,支持以下类型的ApplicationEvent
:
@Override
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
return ApplicationEnvironmentPreparedEvent.class.isAssignableFrom(eventType)
|| ApplicationPreparedEvent.class.isAssignableFrom(eventType)
|| ApplicationFailedEvent.class.isAssignableFrom(eventType);
}
因此,当SpringApplication
准备好Envirmonent
并发布ApplicationEnvironmentPreparedEvent
事件,会回调其onApplicationEvent(ApplicationEvent)
方法,从而触发onApplicationEnvironmentPreparedEvent()
方法:
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ApplicationEnvironmentPreparedEvent) {
onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event);
}
if (event instanceof ApplicationPreparedEvent) {
onApplicationPreparedEvent();
}
if (event instanceof ApplicationFailedEvent) {
onApplicationFailedEvent();
}
}
在onApplicationEnvironmentPreparedEvent()
方法中,通过调用SpringFactoriesLoader.loadFactoryNames(EnvironmentPostProcessor.
class, classLoader)
加载声明在/META-INF/spring.factories
文件中的EnvironmentPostProcessor
实例。
本文以服务端口server.port
为例,简述了Spring环境后置处理器的基本使用及其实现原理,开发者可以使用该扩展对Spring默认环境进行处理或自定义, 更大限度地提高程序开发效率。