BeanPostProcessor —— 连接Spring IOC和AOP的桥梁

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对象创建之后,用户使用之前可以加载并执行对应的逻辑的。


image.png

其二: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列表创建好了


image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容