原文: 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 后处理器:

  1. 实现BeanPostProcessor接口。
  2. 实现回调方法。

CustomBeanPostProcessor.java

  1. import org.springframework.beans.BeansException;
  2. import org.springframework.beans.factory.config.BeanPostProcessor;
  3. public class CustomBeanPostProcessor implements BeanPostProcessor
  4. {
  5. public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException
  6. {
  7. System.out.println("Called postProcessBeforeInitialization() for :" + beanName);
  8. return bean;
  9. }
  10. public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException
  11. {
  12. System.out.println("Called postProcessAfterInitialization() for :" + beanName);
  13. return bean;
  14. }
  15. }

1.2. 如何注册BeanPostProcessor

ApplicationContext自动检测在实现BeanPostProcessor接口的配置元数据中定义的所有 bean。 它将这些 bean 注册为后处理器,以便以后在 bean 创建时可以调用它们。

然后,Spring 将在调用初始化回调方法之前和之后将每个 bean 实例传递给这两个方法,在这里您可以按自己喜欢的方式处理 bean 实例。

  1. <beans>
  2. <bean id="customBeanPostProcessor"
  3. class="com.howtodoinjava.demo.processors.CustomBeanPostProcessor" />
  4. </beans>

2. 调用BeanPostProcessor方法时

通常,spring 的 DI 容器会执行以下操作来创建一个 bean,您需要:

  1. 通过构造函数或工厂方法创建 Bean 实例
  2. 设置值和对 bean 属性的 bean 引用
  3. 调用所有感知接口中定义的 setter 方法
  4. 将 bean 实例传递给每个 bean 后处理器的postProcessBeforeInitialization()方法
  5. 调用初始化回调方法
  6. 将 bean 实例传递给每个 bean 后处理器的postProcessAfterInitialization()方法
  7. Bean 已准备好使用
  8. 关闭容器后,调用销毁回调方法

3. Spring BeanPostProcessor示例

为了显示示例用法,我正在使用EmployeeDAOImpl类,如下所示:

EmployeeDAOImpl.java

  1. public class EmployeeDAOImpl implements EmployeeDAO
  2. {
  3. public EmployeeDTO createNewEmployee()
  4. {
  5. EmployeeDTO e = new EmployeeDTO();
  6. e.setId(1);
  7. e.setFirstName("Lokesh");
  8. e.setLastName("Gupta");
  9. return e;
  10. }
  11. public void initBean() {
  12. System.out.println("Init Bean for : EmployeeDAOImpl");
  13. }
  14. public void destroyBean() {
  15. System.out.println("Init Bean for : EmployeeDAOImpl");
  16. }
  17. }

该 bean 及其后处理器的配置如下:

beans.xml

  1. <bean id="customBeanPostProcessor" class="com.howtodoinjava.demo.processors.CustomBeanPostProcessor" />
  2. <bean id="dao" class="com.howtodoinjava.demo.dao.EmployeeDAOImpl" init-method="initBean" destroy-method="destroyBean"/>

现在,启动 DI 容器并查看输出:

Demo.java

  1. ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

Console

  1. Called postProcessBeforeInitialization() for : dao
  2. Init Bean for : EmployeeDAOImpl
  3. Called postProcessAfterInitialization() for : dao

显然,在初始化方法之前和之后都调用了BeanPostProcessor方法。

学习愉快!