原文: https://howtodoinjava.com/spring-core/spring-bean-post-processors/
bean 后处理器允许自定义修改 spring bean 工厂创建的新 bean 实例。 如果您想在 Spring 容器完成实例化,配置和初始化 bean 之后实现一些自定义逻辑,我们可以插入一个或多个BeanPostProcessor
实现。
对于多个BeanPostProcessor
实例,我们可以通过设置order
属性或实现Ordered
接口来控制顺序。
1. Spring BeanPostProcessor
BeanPostProcessor
接口恰好由两个回调方法组成,即postProcessBeforeInitialization()
和postProcessAfterInitialization()
。
对于由容器创建的每个 bean 实例,后处理器都会同时从容器获取回调 – 在调用容器初始化方法之前以及任何 bean 初始化回调之后 。
Bean 后处理器通常检查回调接口,或者可以使用代理包装 Bean。 一些 Spring AOP 基础结构类(例如AbstractAdvisingBeanPostProcessor
)被实现为 bean 后处理器,以提供代理包装逻辑。
1.1. 如何创建BeanPostProcessor
要在 Spring 创建一个 bean 后处理器:
- 实现
BeanPostProcessor
接口。 - 实现回调方法。
CustomBeanPostProcessor.java
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class CustomBeanPostProcessor implements BeanPostProcessor
{
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException
{
System.out.println("Called postProcessBeforeInitialization() for :" + beanName);
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException
{
System.out.println("Called postProcessAfterInitialization() for :" + beanName);
return bean;
}
}
1.2. 如何注册BeanPostProcessor
ApplicationContext
自动检测在实现BeanPostProcessor
接口的配置元数据中定义的所有 bean。 它将这些 bean 注册为后处理器,以便以后在 bean 创建时可以调用它们。
然后,Spring 将在调用初始化回调方法之前和之后将每个 bean 实例传递给这两个方法,在这里您可以按自己喜欢的方式处理 bean 实例。
<beans>
<bean id="customBeanPostProcessor"
class="com.howtodoinjava.demo.processors.CustomBeanPostProcessor" />
</beans>
2. 调用BeanPostProcessor
方法时
通常,spring 的 DI 容器会执行以下操作来创建一个 bean,您需要:
- 通过构造函数或工厂方法创建 Bean 实例
- 设置值和对 bean 属性的 bean 引用
- 调用所有感知接口中定义的 setter 方法
- 将 bean 实例传递给每个 bean 后处理器的
postProcessBeforeInitialization()
方法 - 调用初始化回调方法
- 将 bean 实例传递给每个 bean 后处理器的
postProcessAfterInitialization()
方法 - Bean 已准备好使用
- 关闭容器后,调用销毁回调方法
3. Spring BeanPostProcessor
示例
为了显示示例用法,我正在使用EmployeeDAOImpl
类,如下所示:
EmployeeDAOImpl.java
public class EmployeeDAOImpl implements EmployeeDAO
{
public EmployeeDTO createNewEmployee()
{
EmployeeDTO e = new EmployeeDTO();
e.setId(1);
e.setFirstName("Lokesh");
e.setLastName("Gupta");
return e;
}
public void initBean() {
System.out.println("Init Bean for : EmployeeDAOImpl");
}
public void destroyBean() {
System.out.println("Init Bean for : EmployeeDAOImpl");
}
}
该 bean 及其后处理器的配置如下:
beans.xml
<bean id="customBeanPostProcessor" class="com.howtodoinjava.demo.processors.CustomBeanPostProcessor" />
<bean id="dao" class="com.howtodoinjava.demo.dao.EmployeeDAOImpl" init-method="initBean" destroy-method="destroyBean"/>
现在,启动 DI 容器并查看输出:
Demo.java
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Console
Called postProcessBeforeInitialization() for : dao
Init Bean for : EmployeeDAOImpl
Called postProcessAfterInitialization() for : dao
显然,在初始化方法之前和之后都调用了BeanPostProcessor
方法。
学习愉快!