SpringBoot bean的常用扩展点
了解Spring这些扩展点,有助于我们编写更优雅的代码。扩展点的具体应用实践,我们可以多看优秀的源码借鉴思路。
扩展点顺序
几个阶段:
- 容器级
- 对象实例化阶段(实例化前、实例化、实例化后)
- Aware回调
- 初始化阶段(初始化前、初始化、初始化后)
- 使用bean
- 销毁阶段
flowchart TD
A["【1】BeanFactoryPostProcessor<br/>postProcessBeanFactory"] --> B["【2】InstantiationAwareBeanPostProcessor<br/>postProcessBeforeInstantiation"]
B --> C["【3】Chat 构造函数<br/>construct(实例化)"]
C --> D["【4】InstantiationAwareBeanPostProcessor<br/>postProcessAfterInstantiation"]
D --> E["【5】BeanNameAware<br/>setBeanName"]
E --> F["【6】BeanFactoryAware<br/>setBeanFactory"]
F --> G["【7】ApplicationContextAware<br/>setApplicationContext"]
G --> H["【8】BeanPostProcessor<br/>postProcessBeforeInitialization"]
H --> I["【9】@PostConstruct<br/>init(初始化)"]
I --> J["【10】InitializingBean<br/>afterPropertiesSet(初始化)"]
J --> K["【11】BeanPostProcessor<br/>postProcessAfterInitialization"]
K --> L["... bean 正常使用 ..."]
L --> M["【12】@PreDestroy<br/>preDestroy(销毁前)"]
M --> N["【13】DisposableBean<br/>destroy(销毁)"]
subgraph 容器级["容器级(全局,仅一次)"]
A
end
subgraph 实例化阶段["实例化阶段"]
B
C
D
end
subgraph Aware阶段["Aware 回调阶段"]
E
F
G
end
subgraph 初始化阶段["初始化阶段"]
H
I
J
K
end
subgraph 销毁阶段["销毁阶段"]
M
N
end
| 顺序 | 扩展点 / 方法 | 所属接口或注解 | 阶段 | 生效范围 | 说明 |
|---|---|---|---|---|---|
| 1 | postProcessBeanFactory | BeanFactoryPostProcessor | 容器级 | 容器(一次) | 容器 BeanFactory 构建后回调,可干预 bean 定义 |
| 2 | postProcessBeforeInstantiation | InstantiationAwareBeanPostProcessor | 实例化前 | 所有 bean | bean 实例化(new)之前调用 |
| 3 | Chat() 构造函数 | bean 自身 | 实例化 | 单个 bean | 无参构造函数调用,完成实例化 |
| 4 | postProcessAfterInstantiation | InstantiationAwareBeanPostProcessor | 实例化后 | 所有 bean | bean 实例化(new)之后调用 |
| 5 | setBeanName | BeanNameAware | Aware 回调 | 单个 bean | 注入 bean 的名称 |
| 6 | setBeanFactory | BeanFactoryAware | Aware 回调 | 单个 bean | 注入 BeanFactory 容器 |
| 7 | setApplicationContext | ApplicationContextAware | Aware 回调 | 单个 bean | 注入 ApplicationContext(继承自 BeanFactory) |
| 8 | postProcessBeforeInitialization | BeanPostProcessor | 初始化前 | 所有 bean | 初始化前调用,bean 放入上下文之前 |
| 9 | init | @PostConstruct 注解 | 初始化 | 单个 bean | 注解式初始化方法 |
| 10 | afterPropertiesSet | InitializingBean | 初始化 | 单个 bean | 接口式初始化方法 |
| 11 | postProcessAfterInitialization | BeanPostProcessor | 初始化后 | 所有 bean | 初始化后调用,bean 放入上下文之后 |
| 12 | preDestroy | @PreDestroy 注解 | 销毁前 | 单个 bean | 容器关闭、bean 销毁前调用 |
| 13 | destroy | DisposableBean | 销毁 | 单个 bean | bean 销毁时调用 |
代码
bean 举例
@Service
public class Chat implements InitializingBean, BeanNameAware, BeanFactoryAware, ApplicationContextAware, DisposableBean {
private static ApplicationContext appContext;
public Chat() {
System.out.println("【3】Chat construct. 【bean 无参构造函数调用,实例化】");
}
@PostConstruct
public void init() {
System.out.println("【9】Chat PostConstruct. 【init方法 @PostConstruct注解,初始化bean】");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("【10】Chat afterPropertiesSet. 【bean 实现InitializingBean接口,初始化bean】");
}
public void say() {
System.out.println("say something");
}
/**
* 单个bean 生效
*/
@Override
public void setBeanName(String name) {
System.out.println("【5】BeanNameAware setBeanName, name: " + name + ". 【实现 BeanNameAware接口】");
}
/**
* BeanFactoryAware 单个bean生效
* @throws BeansException
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("【6】BeanFactoryAware setBeanFactory. 【实现 BeanFactoryAware 接口,传入bean容器】");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("【7】ApplicationContextAware setApplicationContext. 【实现ApplicationContext接口,其继承自BeanFactory】");
appContext = applicationContext;
}
public <T> T getBean(String beanName, Class<T> requiredType) {
return appContext.getBean(beanName, requiredType);
}
@PreDestroy
public void preDestroy() {
System.out.println("【12】Chat PreDestroy. 【bean 销毁前调用】");
}
public void destroy() throws Exception {
System.out.println("【13】Chat destroy.【bean 销毁时调用】");
}
}
ApplicationContextAware 容器上下文 举例
@Component
public class AppContext implements ApplicationContextAware {
private static ApplicationContext appContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("ApplicationContextAware setApplicationContext. 【实现ApplicationContext接口】");
appContext = applicationContext;
}
public <T> T getBean(String beanName, Class<T> requiredType) {
return appContext.getBean(beanName, requiredType);
}
public <T> T getBean(Class<T> requiredType) {
return appContext.getBean(requiredType);
}
}
InstantiationAwareBeanPostProcessor 实例化前后 举例
@Component
public class InstantiationBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
/**
* bean 实例化(new obj)之前调用
*/
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if ("chat".equals(beanName)) {
System.out.println("【2】InstantiationAwareBeanPostProcessor postProcessBeforeInstantiation beanName:" + beanName + ". 【实现 InstantiationAwareBeanPostProcessor接口 【实例化,非初始化】前。所有bean生效】");
}
return null;
}
/**
* bean 实例化(new obj)之后调用
*/
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if ("chat".equals(beanName)) {
System.out.println("【4】InstantiationAwareBeanPostProcessor postProcessAfterInstantiation beanName:" + beanName + ". 【实现 InstantiationAwareBeanPostProcessor接口 【实例化,非初始化】后】。所有bean生效");
}
return true;
}
/**
* 所有bean 都可生效
* InstantiationAwareBeanPostProcessor 继承自 BeanPostProcessor
* 初始化bean前调用,bean放到spring上下文之前
*/
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("chat")) {
System.out.println("【8】BeanPostProcessor postProcessBeforeInitialization. 【BeanPostProcessor 初始化前调用。所有bean 都可生效】");
}
return bean;
}
/**
* 所有bean 都可生效
* InstantiationAwareBeanPostProcessor 继承自 BeanPostProcessor
* 初始化bean后调用,bean放到spring上下文之后
*/
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("chat")) {
System.out.println("【11】BeanPostProcessor postProcessAfterInitialization. 【BeanPostProcessor 初始化后调用。所有bean 都可生效】");
}
return bean;
}
}
BeanFactoryPostProcessor 容器 举例
@Component
public class BeanFactoryPostProcess implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("【1】BeanFactoryPostProcessor postProcessBeanFactory. 【BeanFactoryPostProcessor beanFactory】");
}
}
BeanPostProcessor bean初始化前后 举例
前边的InstantiationAwareBeanPostProcessor 继承自 BeanPostProcessor,也会继承内部这两个方法。
@Component
public class BeanPostProcess implements BeanPostProcessor {
/**
* 所有bean 都可生效
*/
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("chat")) {
System.out.println("【8】BeanPostProcessor postProcessBeforeInitialization. 【BeanPostProcessor 初始化前调用。所有bean 都可生效】");
}
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("chat")) {
System.out.println("【11】BeanPostProcessor postProcessAfterInitialization. 【BeanPostProcessor 初始化后调用。所有bean 都可生效】");
}
return bean;
}
}
总结
bean的生命周期和SpringBoot开发中常用扩展点。
- bean整个容器、上下文的构造。
- 各个bean的实例化前后、初始化前后,可干预的扩展点。