• 分析-BeanPostProceesor后置处理器


    目录

    一、概述

    二、创建后置处理器过程

    三、不同BeanPostProcessor接口调用流程

    3.1 InstantiationAwareBeanPostProcessor

    3.2 MergedBeanDefinitionPostProcessor

    3.3 BeanPostProcessor

    3.4 DestructionAwareBeanPostProcessor


    一、概述

    BeanPostProcessor后置处理器是在容器创建bean对象对象初始化时前后调用对应方法。

    例如:

    1、InstantiationAwareBeanPostProcessor:在容器创建组件对象之前,给后置处理器一个机会,后置处理器可返回该组件的代理对象,容器不再需要去创建、初始化组件对象。

    调用方法:postProcessBeforeInstantiation

                      postProcessAfterInstantiation    

                      postProcessProperties(用来代替postProcessPropertyValues方法)

                      postProcessPropertyValues

    2、MergedBeanDefinitionPostProcessor:在容器创建完组件对象,还未设置属性值,初始化时,后置处理器可对RootBeanDefinition(MergedBeanDefinition)进行操作。

    调用方法:postProcessMergedBeanDefinition

    具体用法可参考:

    什么是MergedBeanDefinition?_jiangjun316的博客-CSDN博客

    3、BeanPostProcessor:在组件对象初始化前后调用。

    例如:AutowiredAnnotationBeanPostProcessor处理@Autowired、@Value注解

               CommonAnnotationBeanPostProcessor处理@Resource、@Inject注解

    调用方法:

                    postProcessBeforeInitialization

                    postProcessAfterInitialization

    4、DestructionAwareBeanPostProcessor:在容器组件进行销毁之前调用

    调用方法:

                    postProcessBeforeDestruction

                    requiresDestruction(设置组件是否需要Destrction后置处理器处理)

    二、创建后置处理器过程

    通过容器的refresh方法的registerBeanPostProcessor方法创建BeanPostProcessor接口对象并添加到容器的beanPostProcessors集合中。

     先从容器获取到所有实现BeanPostProcessor接口的postProcessorNames集合,

     1、按照优先级顺序,先创建实现PriorityOrder接口的BeanPostProcessor对象,如果该对象实现MergedBeanDefinitionPostProcessor接口,则将对象加到internalPostProcessors集合中,

    2、再创建实现Order接口的BeanPostProcessor对象,如果该对象实现MergedBeanDefinitionPostProcessor接口,则将对象加到internalPostProcessors集合中,

    3、创建没实现PriorityOrderOrder接口的BeanPostProcessor对象,如果该对象实现MergedBeanDefinitionPostProcessor接口,则将对象加到internalPostProcessors集合中,

    4、将internalPostProcessors集合中的后置处理器对象重新添加到容器的beanPostProcessorss集合中。

     5、最后创建ApplicationListenerDetector后置处理器对象并添加到beanPostProcessors集合中。(ApplicationListenerDetector主要用来处理实现ApplictionListener接口的事件监听器)

     

    三、不同BeanPostProcessor接口调用流程

    3.1 InstantiationAwareBeanPostProcessor

    该接口实现类可在容器创建组件对象之前返回组件的对象或代理对象,不需要容器去创建组件对象。

    1、容器创建组件对象调用createBean方法,在调用doCreateBean方法创建对象之前,调用resolveBeforeInstantiation方法,若是方法返回的bean不为空,则说明后置处理器已经创建了该组件的对象(或代理对象),不需要容器在去创建对象,直接返回bean对象。

    1.1、resolveBeforeInstantiation方法中调用applyBeanPostProcessorsBeforeInstantiation方法,若方法返回的bean不为空,则调用applyBeanPostProcessorsAfterInitialization方法。

    1.2、applyBeanPostProcessorsBeforeInstantiation方法遍历容器的beanPostProcessors集合,调用实现InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法,若是方法返回的result不为空,说明后置处理器已经创建了该组件的对象或代理对象,直接返回result,不再遍历后置处理器集合。

     1.3、applyBeanPostProcessorsAfterInitialization方法遍历容器的beanPostProcessors集合,调用所有beanPostProcessor对象postProcessAfterInitialization方法。

    2、若是resolveBeforeInstantiation方法返回的bean为空,则说明需要容器继续往下进行去创建组件对象,在容器创建完组件对象后,在populateBean方法遍历容器的beanPostProcessors集合,调用InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation方法。

    3、 最后遍历容器的beanPostProcessors集合,调用 

    InstantiationAwareBeanPostProcessor接口的postProcessProperties方法,若是postProcessProperties方法返回结果为null,则调用postProcessPropertyValues方法。

    3.2 MergedBeanDefinitionPostProcessor

    MergedBeanDefinitionPostProcessor后置处理器可在容器创建完组件对象后,调用postProcessMergedBeanDefinition方法操作修改RootBeanDefinition(MergedBeanDefinition)的信息。

    1、在doCreateBean方法中,调用applyMergedBeanDefinitionPostProcessors方法,

     2、applyMergedBeanDefinitionPostProcessors方法遍历容器的beanPostProcessors集合,找到实现MergedBeanDefinitionPostProcessor接口的实现类对象,调用postProcessMergedBeanDefinition方法操作修改RootBeanDefinition(MergedBeanDefinition)的信息。

    3、MergedBeanDefinitionPostProcessorresetBeanDefinition方法可用来容器对beanDefinition进行reset时,做一些处理。

    例如使用容器使用removeBeanDefinition方法移除beanDefinition时,removeBeanDefinition方法会调用容器的resetBeanDefinition方法,resetBeanDefinition方法中会遍历容器的beanPostProcessors集合,找到实现MergedBeanDefinitionPostProcessor接口的实现类,调用resetBeanDefinition方法。

    参考:

    什么是MergedBeanDefinition?_jiangjun316的博客-CSDN博客

    3.3 BeanPostProcessor

    BeanPostProcessor在容器创建完组件,组件初始化前后调用postProcessBeforeInitializationpostProcessAfterInitialization方法,若是InstantiationAwareBeanPostProcessor接口实现类返回该组件的对象或代理对象,则只执行postProcessAfterInitialization方法。

    1、容器创建完组件,准备初始化时,调用initializeBean方法,在initializeBean中,调用applyBeanPostProcessorsBeforeInitialization方法,

     2、applyBeanPostProcessorsBeforeInitialization方法遍历容器的beanPostPrcessors集合,调用后置处理器的postProcessBeforeInitialization方法,

     3、组件初始化完后,调用applyBeanPostProcessorsAfterInitialization方法,

     4、applyBeanPostProcessorsAfterInitialization方法遍历容器的beanPostPrcessors集合,调用后置处理器的postProcessAfterInitialization方法。

    3.4 DestructionAwareBeanPostProcessor

    DustructionAwareBeanPostProcessor后置处理器是用来容器销毁组件对象前调用postProcessBeforeDestruction方法进行某些处理操作。

    注意:1、若组件是prototype多例,则无法使用销毁后置处理器。

               2、如果组件对象是通过我们自定义的InstantiationAwareBeanPostProcessor接口的后置处理器返回的组件对象,则对象销毁时,销毁后置处理器不会处理该对象。若是想通过自定义创建的组件对象也能使用销毁后置处理器,可参考

    解决通过后置处理器返回组件对象无法使用销毁后置处理器和销毁方法_Just-Today的博客-CSDN博客

    1、在容器创建初始化完组件对象后,调用doCreateBean方法的registerDisposableBeanIfNecessary方法,

    2、 在 registerDisposableBeanIfNecessary方法中,先判断组件是否是prototype多例,若是多例,则直接返回,若不是,调用requiresDestruction方法,

    3、 通过DisposableBeanAdapter.hasApplicableProcessors方法遍历容器的beanPostProcessors集合,

    4、 找到实现DestructionAwareBeanPostProcessor接口的实现类对象,调用requiresDestruction方法判断该组件对象是否需要销毁后置处理器进行处理,若有,返回true,

    5、先创建DisposableBeanAdapter对象,

     6、在DisposableBeanAdapter构造函数中,通过filterPostProcessors方法遍历容器的beanPostProcessors集合,找到实现DestructionAwareBeanPostProcessor接口的实现类对象,通过该后置处理器的requiresDestruction方法判断是否需要处理该组件对象,若需要,则将后置处理器添加到DisposableBeanAdapter对象的beanPostProcessors集合中, 

    7、 通过registerDisposableBean方法将组件名称和DisposableBean对象保存到容器的disposableBeans集合中,

     8、在容器销毁组件对象时,会根据组件名称从容器的disposableBeans集合中找到DisposableBeanAdapter对象,

    9、在destroyBean方法中,调用DisposableBeanAdapter对象的destroy方法

    10、在destroy方法中,遍历保存在DisposableBeanAdapter对象的beanPostProcessors集合,调用postProcessBeforeDestruction方法。

  • 相关阅读:
    Java小树的参天成长(构造方法重载)
    【图像压缩】基于matlab二叉树和优化截断(BTOT)遥感图像压缩【含Matlab源码 2043期】
    #FreeRTOS延时函数
    Java反射调用jar包实现多态
    手把手教你解决ClassCastException类型转换异常
    SQL Server 修改、删除表中数据
    四、神经网络语言模型(NNLM)
    iOS小技能:苹果书签打包教程【WebClip描述文件(WebClip Configuration Profile)】
    Java入门基础第4天《Java编程规范及编译源代码常见错误的解决方法》
    RGB灯带蓝牙芯片智能化方案
  • 原文地址:https://blog.csdn.net/weixin_37607613/article/details/126294818