1.什么是BeanPostProcessor (BBP)
BBP是连接连接Spring IOC和AOP的桥梁,它的作用是可以让Spring 注入的bean在创建之后,做一些公用的功能,对外暴露给应用开发者,比如AOP的切面编程,Spring事务都是基于BBP的接口暴露做出来的,可以说BBP是Spring是重点。
2.怎么用?
一般而言,我们大多数场景,会用postProcessBeforeInitialization和postProcessAfterInitialization两个方法居多,继承BeanPostProcessor接口类。(不过,spring 也有些方法是基于BeanPostProcessor做扩展的,也可以用扩展后的接口类,功能会丰富一点)
/**
* @program: demo
* @description: 一个简单的spring注入bean
*/
@Component
public class BeanBbp {
private static final Logger logger= LoggerFactory.getLogger(BeanBbp.class);
public BeanBbp() {
logger.info("执行BeanBbp 构造函数");
}
}
/**
* @program: demo
* @description: BeanPostProcessor实现类,Spring 核心实现,是连接IOC和AOP的桥梁------------
* 自定义BeanPostProcessor实现类
*/
/**
* 可以看出,执行的逻辑顺序是先执行Bean的构造函数,在执行postProcessBeforeInitialization和postProcessAfterInitialization方法
* 意味着,这2个方法都是在bean创建之后,才执行的,不要被before误导了,这就叫做对象后处理器
* 执行BeanBbp 构造函数
* 执行CustomBeanPostProcessor->postProcessBeforeInitialization 构造函数beanBbp
* 执行CustomBeanPostProcessor->postProcessAfterInitialization 构造函数beanBbp
*/
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
private static final Logger logger= LoggerFactory.getLogger(CustomBeanPostProcessor.class);
public CustomBeanPostProcessor() {
logger.info("执行CustomBeanPostProcessor 构造函数");
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if("beanBbp".equals(beanName)){
logger.info("执行CustomBeanPostProcessor->postProcessBeforeInitialization 构造函数"+beanName);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
logger.info("执行CustomBeanPostProcessor->postProcessAfterInitialization 构造函数"+beanName);
return bean;
}
}
通过上面2段代码及执行结果可以看出,执行的逻辑顺序是先执行Bean的构造函数,在执行postProcessBeforeInitialization和postProcessAfterInitialization方法意味着,这2个方法都是在bean创建之后,才执行的,不要被before误导了,这就叫做对象后处理器。
3.BBP原理
如图所示:这是Spring官网初始化Bean的流程,可以看出 BBP是基于bean对象创建之后,用户使用之前可以加载并执行对应的逻辑的。

其二:BPP是面向接口的,可以定义多个,因此,基于每个bean,在源码实现的时候,都是会遍历每一个BPP的实现类去做的,如下面源码所示。
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
Object current;
for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) {
BeanPostProcessor processor = (BeanPostProcessor)var4.next();
current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
}
return result;
}
其三,postProcessBeforeInitialization和postProcessAfterInitialization区别是什么呢,既然都是在对象创建之后,为啥要搞2个方法。
这里着重强调下,postProcessBeforeInitialization和postProcessAfterInitialization中间还隔了个对象invoke方法,比如对象要设置XXX属性或者什么之类的,都是在invoke实现,这就是对应着AOP切面前后的关系,一模一样。
其四:BBP对象是在什么时候被构建的呢,当然必须在普通对象创建之前被创建。
我们可以通过任意一个BBP实例化对象的构造函数中打断点,跟进得出:这个方法里面调用了registerBeanPostProcessors方法,里头就已经把BBP列表创建好了
