首页 > Spring 阅读:10,916

BeanPostProcessor(Spring后置处理器)

本节主要介绍在《Spring Bean生命周期》一节提到的 BeanPostProcessor 接口。

BeanPostProcessor 接口也被称为后置处理器,通过该接口可以自定义调用初始化前后执行的操作方法。

BeanPostProcessor 接口源码如下:
public interface BeanPostProcessor {
    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;

    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
postProcessBeforeInitialization 在 Bean 实例化、依赖注入后,初始化前调用。postProcessAfterInitialization 在 Bean 实例化、依赖注入、初始化都完成后调用。

当需要添加多个后置处理器实现类时,默认情况下 Spring 容器会根据后置处理器的定义顺序来依次调用。也可以通过实现 Ordered 接口的 getOrder 方法指定后置处理器的执行顺序。该方法返回值为整数,默认值为 0,值越大优先级越低。

示例

下面使用 Eclipse IDE 演示 BeanPostProcessor 接口的用法,步骤如下:
  1. 创建 SpringDemo 项目,并在 src 目录下创建 net.biancheng 包。
  2. 添加相应的 jar 包,可以参考《第一个Spring程序》一节。
  3. 在 net.biancheng 包下创建 HelloWorld、InitHelloWorld、InitHelloWorld2 和 MainApp 类。
  4. 在 src 目录下创建 Spring 配置文件 Beans.xml。
  5. 运行 SpringDemo 项目。

HelloWorld 类代码如下。
package net.biancheng;

public class HelloWorld {
    private String message;

    public void setMessage(String message) {
        this.message = message;
    }

    public void getMessage() {
        System.out.println("Message : " + message);
    }

    public void init() {
        System.out.println("Bean正在初始化");
    }

    public void destroy() {
        System.out.println("Bean将要被销毁");
    }
}
InitHelloWorld 类代码如下。
package net.biancheng;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;

public class InitHelloWorld implements BeanPostProcessor, Ordered {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("A Before : " + beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("A After : " + beanName);
        return bean;
    }

    @Override
    public int getOrder() {
        return 5;
    }
}
需要注意的是,postProcessBeforeInitialization 和 postProcessAfterInitialization 方法返回值不能为 null,否则会报空指针异常或者通过 getBean() 方法获取不到 Bean 实例对象,因为后置处理器从Spring IoC 容器中取出 Bean 实例对象后没有再次放回到 IoC 容器中。

InitHelloWorld2 的代码如下。
package net.biancheng;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;

public class InitHelloWorld2 implements BeanPostProcessor, Ordered {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("B Before : " + beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("B After : " + beanName);
        return bean;
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
Beans.xml 代码如下。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean id="helloWorld" class="net.biancheng.HelloWorld"
        init-method="init" destroy-method="destroy">
        <property name="message" value="Hello World!" />
    </bean>

    <!-- 注册处理器 -->
    <bean class="net.biancheng.InitHelloWorld" />
    <bean class="net.biancheng.InitHelloWorld2" />
</beans>
MainApp 类代码如下。
package net.biancheng;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
    public static void main(String[] args) {
        AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

        HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
        obj.getMessage();
        context.registerShutdownHook();
    }
}
运行结果如下。

B Before : helloWorld
A Before : helloWorld
Bean正在初始化
B After : helloWorld
A After : helloWorld
Message : Hello World!
Bean将要被销毁


由运行结果可以看出,postProcessBeforeInitialization 方法是在 Bean 实例化和依赖注入后,自定义初始化方法前执行的。而 postProcessAfterInitialization 方法是在自定义初始化方法后执行的。由于 getOrder 方法返回值越大,优先级越低,所以 InitHelloWorld2 先执行。

关注微信公众号「站长严长生」,在手机上阅读所有教程,随时随地都能学习。本公众号由C语言中文网站长运营,每日更新,坚持原创,敢说真话,凡事有态度。

魏雪原二维码
微信扫描二维码关注公众号