Spring中BeanPostProcessor

来源:互联网 发布:植物折纸软件 编辑:程序博客网 时间:2024/05/20 14:19

BeanPostProcessor:如果我们需要在Spring容器完成Bean的实例化、配置和其他的初始化(init-method标识的方法)前后添加一些自己的逻辑处理,我们就可以定义一个或者多个BeanPostProcessor接口的实现,然后注册到容器中。

Spring中Bean的实例化过程:
这里写图片描述

Spring在配置完bean以后,会检查bean是否实现了InitializingBean接口,如果实现就调用bean的afterPropertiesSet方法。另外,如果bean是单例的,则afterPropertiesSet方法只会被调用一次;否则每次创建bean时afterPropertiesSet方法都会被重新调用.
同时Spring也可以通过配置init-method来实现加载配置后的方法调用,如果bean实现了InitializingBean接口,则会先调用bean的afterPropertiesSet方法再去调用bean的init-method方法。需要注意的是init-method中定义的方法不能够有参数,否则抛出异常。

BeanPostProcessor接口有两个方法需要实现:

public interface BeanPostProcessor {    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;}

BeanPostProcessor接口实现:

package com.xiya.entity;import org.springframework.beans.BeansException;import org.springframework.beans.factory.config.BeanPostProcessor;public class MyBeanPostProcessor implements BeanPostProcessor {    @Override    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {        if (bean instanceof Chinese) {            System.out.println("Before-->" + beanName);        }        return bean;    }    @Override    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {        if (bean instanceof Chinese) {            System.out.println("After-->" + beanName);        }        return bean;    }}

另外,接口中的两个方法都要将传入的bean返回,而不能返回null,如果返回的是null那么我们通过getBean方法将得不到目标。


InitializingBean 接口:

public interface InitializingBean {    void afterPropertiesSet() throws Exception;}

An alternative to implementing InitializingBean is specifying a custom init-method, for example in an XML bean definition.

实现InitializingBean的替代方法是在XML bean指定一个自定义的init-method。

package com.xiya.entity;public class Student {    public void init() {        System.out.println("init");    }}//在 Spring 配置文件中如下配置<bean id="person" class="com.xiya.entity.Student" init-method="init"/>

其实有三种自定义实现完成bean初始化后/销毁前的操作:

通过实现 InitializingBean/DisposableBean 接口来定制初始化之后/销毁之前的操作方法;
通过 <bean> 元素的 init-method destroy-method 属性指定初始化之后/销毁之前调用的操作方法;
在指定方法上加上@PostConstruct@PreDestroy注解来制定该方法是在初始化之后还是销毁之前调用。

以上三种的执行顺序:
默认Constructor > @PostConstruct > InitializingBean.afterPropertiesSet > init-method
这里写图片描述

这里写图片描述


在阅读源码的过程中,我们也深刻的体会到库和框架的区别:

  • 你使用库
  • 框架使用你

而回调机制则是框架实现的途径。

参考:
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/config/BeanPostProcessor.html

http://uule.iteye.com/blog/2094549

http://www.jianshu.com/p/fb39f568cd5e

http://www.cnblogs.com/jyyzzjl/p/5417418.html

http://www.cnblogs.com/fangjian0423/p/spring-beanPostProcessor.html