# Spring `BeanPostProcessor`示例

> 原文： [https://howtodoinjava.com/spring-core/spring-bean-post-processors/](https://howtodoinjava.com/spring-core/spring-bean-post-processors/)

**bean 后处理器**允许自定义修改 spring [bean 工厂](https://howtodoinjava.com/spring-core/different-spring-ioc-containers/)创建的新 bean 实例。 如果您想在 Spring 容器完成实例化，配置和初始化 bean 之后实现一些自定义逻辑，我们可以插入一个或多个`BeanPostProcessor`实现。

对于多个`BeanPostProcessor`实例，我们可以通过设置`order`属性或实现[`Ordered`](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/Ordered.html)接口来控制顺序。

## 1\. Spring `BeanPostProcessor`

`BeanPostProcessor`接口恰好由两个回调方法组成，即`postProcessBeforeInitialization()`和`postProcessAfterInitialization()`。

对于由容器创建的每个 bean 实例，后处理器都会同时从容器获取回调 – 在调用容器初始化方法之前以及任何 bean 初始化回调之后 。

Bean 后处理器通常检查回调接口，或者可以使用代理包装 Bean。 一些 Spring AOP 基础结构类（例如[`AbstractAdvisingBeanPostProcessor`](https://github.com/spring-projects/spring-framework/blob/master/spring-aop/src/main/java/org/springframework/aop/framework/AbstractAdvisingBeanPostProcessor.java)）被实现为 bean 后处理器，以提供代理包装逻辑。

## 1.1. 如何创建`BeanPostProcessor`

要在 Spring 创建一个 bean 后处理器：

1.  实现[`BeanPostProcessor`](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/config/BeanPostProcessor.html)接口。
2.  实现回调方法。

`CustomBeanPostProcessor.java`

```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 实例。

```java
<beans>
     <bean id="customBeanPostProcessor" 
               class="com.howtodoinjava.demo.processors.CustomBeanPostProcessor" />
</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`

```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`

```java
<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`

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

```

`Console`

```java
Called postProcessBeforeInitialization() for : dao
Init Bean for : EmployeeDAOImpl
Called postProcessAfterInitialization() for : dao

```

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

学习愉快！