SpringBoot启动扩展点整理
1. 前言
在Springboot服务启动阶段,Springboot提供了许多扩展点。在实际的业务开发过程中,部分特殊的业务需求需要再Springboot服务启动过程中动态的加载配置或者执行业务处理,特此将常用的Springboot启动扩展点做一个简单的整理。
2. 准备阶段
2.1 EnvironmentPostProcessor
- 接口路径
org.springframework.boot.env.EnvironmentPostProcessor
- 官方说明
- 允许在刷新应用程序上下文之前自定义应用程序的Environment
- 需要在
META-INF/spring.factories
文件中定义
Allows for customization of the application's {@link Environment} prior to the application context being refreshed.
EnvironmentPostProcessor implementations have to be registered in {@code META-INF/spring.factories}, using the fully qualified name of this class as the key.
- 应用场景
可以加载自定义的配置文件并添加至Environment中
- 回调时机
- 代码示例
public class DemoEnvironmentPostProcessor implements EnvironmentPostProcessor {
@Override
public void postProcessEnvironment(@NonNull ConfigurableEnvironment environment, @NonNull SpringApplication application) {
System.out.println(">>> 执行EnvironmentPostProcessor.postProcessEnvironment()方法");
}
}
- 生效方式
在META-INF/spring.factories
文件中添加内容
org.springframework.boot.env.EnvironmentPostProcessor = com.example.demo.extension.DemoEnvironmentPostProcessor
2.2 ApplicationContextInitializer
- 接口路径
org.springframework.context.ApplicationContextInitializer
- 应用场景
Spring会在容器刷新之前调用此类的initialize
方法,可以激活一些配置或者获取Enviroment进行一些业务处理。
- 回调时机
- 代码示例
public class DemoApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(@NonNull ConfigurableApplicationContext applicationContext) {
System.out.println(">>> 执行ApplicationContextInitializer.initialize()方法");
}
}
-
生效方式
在
META-INF/spring.factories
文件中添加内容org.springframework.context.ApplicationContextInitializer = com.example.demo.extension.DemoApplicationContextInitializer
3. 刷新上下文容器阶段
这部分的接口在执行refreshContext(context)
方法刷新上下文的过程中回调。
3.1 BeanDefinitionRegistryPostProcessor
- 接口路径
org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor
- 应用场景
这个接口在读取项目中的beanDefinition
之后执行,提供一个补充的扩展点,动态注册自己的beanDefinition
,可以加载classpath之外的bean。
- 回调时机
- 代码示例
@Component
public class DemoBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(@NonNull BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
System.out.println(">>> 执行BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()方法");
}
@Override
public void postProcessBeanFactory(@NonNull ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println(">>> 执行BeanDefinitionRegistryPostProcessor.postProcessBeanFactory()方法");
}
}
3.2 BeanFactoryPostProcessor
- 接口路径
org.springframework.beans.factory.config.BeanFactoryPostProcessor
- 应用场景
这个接口是beanFactory
的扩展接口,调用时机在spring在读取beanDefinition
信息之后,实例化bean之前。在这个时机,用户可以通过实现这个扩展接口来自行处理一些东西,比如修改已经注册的beanDefinition
的元信息。
- 回调时机
在AbstractApplicationContext
类的refresh
方法中被执行。
- 代码示例
@Component
public class DemoBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(@NonNull ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println(">>> 执行 BeanFactoryPostProcessor.postProcessBeanFactory()方法");
}
}
3.3 BeanFactoryAware和EnvironmentAware
- 接口路径
org.springframework.beans.factory.BeanFactoryAware
org.springframework.context.EnvironmentAware
- 应用场景
在bean实例化和属性注入之后执行,可以在bean初始化之前注入BeanFactory
、Environment
等在初始化阶段使用。
- 回调时机
在AbstractAutowireCapableBeanFactory
类的createBean
方法创建bean的过程中执行。
- 代码示例
@Component
public class DemoBeanFactoryAware implements BeanFactoryAware {
@Override
public void setBeanFactory(@NonNull BeanFactory beanFactory) throws BeansException {
System.out.println(">>> 执行BeanFactoryAware.setBeanFactory()方法");
}
}
@Component
public class DemoEnvironmentAware implements EnvironmentAware {
@Override
public void setEnvironment(@NonNull Environment environment) {
System.out.println(">>> 执行EnvironmentAware.setEnvironment()方法");
}
}
3.4 InstantiationAwareBeanPostProcessor
- 接口路径
org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor
- 应用场景:
InstantiationAwareBeanPostProcessor
接口在BeanPostProcessor
接口的基础上又扩展了3个方法,共包含5个方法,可以在bean的实例化前后,属性注入阶段以及初始化前后进行业务处理。例如Springboot中就是通过BeanPostProcessor
的实现类来解析bean中带有@KafkaListener
注解的方法来注册Kafka容器。
-
回调时机
-
postProcessBeforeInstantiation方法:在bean实例化之前执行
-
postProcessAfterInstantiation方法:在bean实例化之后执行
-
postProcessProperties方法:在bean属性注入阶段执行
-
postProcessBeforeInitialization方法:在bean初始化之前执行
-
postProcessAfterInitialization方法:在bean初始化之后执行
-
-
代码示例
@Component
public class DemoInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(@NonNull Class<?> beanClass, @NonNull String beanName) throws BeansException {
if (beanClass == DemoService.class) {
System.out.println(">>> 执行 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()方法");
}
return InstantiationAwareBeanPostProcessor.super.postProcessBeforeInstantiation(beanClass, beanName);
}
@Override
public boolean postProcessAfterInstantiation(@NonNull Object bean, @NonNull String beanName) throws BeansException {
if (bean instanceof DemoService) {
System.out.println(">>> 执行 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()方法");
}
return InstantiationAwareBeanPostProcessor.super.postProcessAfterInstantiation(bean, beanName);
}
@Override
public PropertyValues postProcessProperties(@NonNull PropertyValues pvs, @NonNull Object bean, @NonNull String beanName) throws BeansException {
if (bean instanceof DemoService) {
System.out.println(">>> 执行 InstantiationAwareBeanPostProcessor.postProcessProperties()方法");
}
return InstantiationAwareBeanPostProcessor.super.postProcessProperties(pvs, bean, beanName);
}
@Override
public Object postProcessBeforeInitialization(@NonNull Object bean, @NonNull String beanName) throws BeansException {
if (bean instanceof DemoService) {
System.out.println(">>> 执行 InstantiationAwareBeanPostProcessor.postProcessBeforeInitialization()方法");
}
return InstantiationAwareBeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(@NonNull Object bean, @NonNull String beanName) throws BeansException {
if (bean instanceof DemoService) {
System.out.println(">>> 执行 InstantiationAwareBeanPostProcessor.postProcessAfterInitialization()方法");
}
return InstantiationAwareBeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
}
3.5 @PostConstruct注解
- 注解路径
javax.annotation.PostConstruct
- 应用场景
可以在bean的初始化阶段执行初始化方法进行业务处理。
- 回调时机
在AbstractAutowireCapableBeanFactory
类的createBean
方法创建bean的过程中InitDestroyAnnotationBeanPostProcessor
类的postProcessBeforeInitialization
方法中执行。
- 代码示例
@Service
public class DemoService {
@PostConstruct
public void init() {
System.out.println(">>> 执行 @PostConstruct注解方法");
}
}
3.6 InitializingBean
- 接口路径
org.springframework.beans.factory.InitializingBean
- 应用场景
同样可以在执行bean初始化过程中执行业务处理。
- 回调时机
在AbstractAutowireCapableBeanFactory
类的createBean
方法创建bean的过程中AbstractAutowireCapableBeanFactory
类的initializeBean
方法中执行。
- 代码示例
@Component
public class DemoInitializingBean implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println(">>> 执行InitializingBean.afterPropertiesSet()方法");
}
}
3.7 SmartInitializingSingleton
- 接口路径
org.springframework.beans.factory.SmartInitializingSingleton
- 应用场景
在对所有单例对象初始化完毕后,做一些后置的业务处理。
- 回调时机
在类DefaultListableBeanFactory
的preInstantiateSingletons
的方法中执行。
- 代码示例
@Component
public class DemoSmartInitializingSingleton implements SmartInitializingSingleton {
@Override
public void afterSingletonsInstantiated() {
System.out.println(">>> 执行SmartInitializingSingleton.afterSingletonsInstantiated()方法");
}
}
3.8 SmartLifecycle
- 接口路径
org.springframework.context.SmartLifecycle
- 应用场景
在对所有单例对象初始化完毕后,做一些后置的业务处理。SmartLifecycle
在Lifecycle
接口的基础上,扩展了3个方法。
其中,isAutoStartup()
方法返回true
时,Bean将在容器完成刷新阶段执行Lifecycle
接口的start()
方法;getPahase()
方法用于返回SmartLifecycle
的优先级。可结合配置文件的配置项来指定SmartLifecycle
是否自动启动及启动的优先级。
- 回调时机
在AbstractApplicationContext
类的finishRefresh
方法中执行。
- 代码示例
@Component
public class DemoSmartLifecycle implements SmartLifecycle {
@Override
public void start() {
System.out.println(">>> 执行SmartLifecycle.start()方法");
}
@Override
public void stop() {
}
@Override
public boolean isRunning() {
return false;
}
}
4. 执行顺序
通过日志可以看到各个扩展点的实际执行顺序。
>>> 执行EnvironmentPostProcessor.postProcessEnvironment()方法
>>> 执行ApplicationContextInitializer.initialize()方法
>>> 执行 BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()方法
>>> 执行 BeanDefinitionRegistryPostProcessor.postProcessBeanFactory()方法
>>> 执行 BeanFactoryPostProcessor.postProcessBeanFactory()方法
>>> 执行 BeanFactoryAware.setBeanFactory()方法
>>> 执行 EnvironmentAware.setEnvironment()方法
>>> 执行 InitializingBean.afterPropertiesSet()方法
>>> 执行 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()方法
>>> 执行 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()方法
>>> 执行 InstantiationAwareBeanPostProcessor.postProcessProperties()方法
>>> 执行 InstantiationAwareBeanPostProcessor.postProcessBeforeInitialization()方法
>>> 执行 @PostConstruct注解方法
>>> 执行 InstantiationAwareBeanPostProcessor.postProcessAfterInitialization()方法
>>> 执行 SmartInitializingSingleton.afterSingletonsInstantiated()方法
>>> 执行 SmartLifecycle.start()方法