• BeanPostProcessor的五大接口


    BeanPostProcessor

    关于对象初始化前后的回调。

    public interface BeanPostProcessor {
        //该方法在bean实例化完毕(且已经注入完毕),在afterPropertiesSet或自定义init方法执行之前
        @Nullable
        default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            return bean;
        }
        //在afterPropertiesSet或自定义init方法执行之后
        @Nullable
        default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            return bean;
        }
    }
    

    InstantiationAwareBeanPostProcessor

    关于对象实例化前后以及实例化后设置propertyValues的回调

    public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
        //这个方法用来在对象实例化前直接返回一个对象(如代理对象)来代替通过内置的实例化流程创建对象;
        @Nullable
        default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
            return null;
        }
        //在对象实例化完毕执行populateBean之前 如果返回false则spring不再对对应的bean实例进行自动依赖注入。
        default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
            return true;
        }
        //这里是在spring处理完默认的成员属性,应用到指定的bean之前进行回调,可以用来检查和修改属性,最终返回的PropertyValues会应用到bean中
        //@Autowired、@Resource等就是根据这个回调来实现最终注入依赖的属性的。
        @Nullable
        default PropertyValues postProcessPropertyValues(
                PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
            return pvs;
        }
    }
    

     SmartInstantiationAwareBeanPostProcessor

    这个接口主要是spring框架内部来使用

    public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
        //用来返回目标对象的类型(比如代理对象通过raw class获取proxy type 用于类型匹配)
        @Nullable
        default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
            return null;
        }
        //这里提供一个拓展点用来解析获取用来实例化的构造器(比如未通过bean定义构造器以及参数的情况下,会根据这个回调来确定构造器)
        @Nullable
        default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
                throws BeansException {
            return null;
        }
        //获取要提前暴露的bean的引用,用来支持单例对象的循环引用(一般是bean自身,如果是代理对象则需要取用代理引用)
        default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
            return bean;
        }
    }
    

    MergedBeanDefinitionPostProcessor

    用来将merged BeanDefinition暴露出来的回调

    public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {
        //在bean实例化完毕后调用 可以用来修改merged BeanDefinition的一些properties 或者用来给后续回调中缓存一些meta信息使用
        //这个算是将merged BeanDefinition暴露出来的一个回调
        void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
    }
    

    DestructionAwareBeanPostProcessor

    关于处理对象销毁的前置回调
    应用实例:
        ApplicationListenerDetector,这个类是用来注册ApplicationListener实例的,而如果销毁一个对象,不接触这里的引用
        会导致无法进行回收,因此在销毁对象时,会判断如果是ApplicationListener要执行从监听器列表中移除掉。

    public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {
        //这里实现销毁对象的逻辑
        void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;
        //判断是否需要处理这个对象的销毁
        default boolean requiresDestruction(Object bean) {
            return true;
        }
    }
    

    关于BeanPostProcessor中各个回调调用的顺序

    1、InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(beanClass, beanName)
        该方法在创建对象之前会先掉用,如果有返回实例则直接使用不会去走下面创建对象的逻辑,并在之后执行
            BeanPostProcessor.postProcessAfterInitialization(result, beanName)
    2、SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors(beanClass, beanName)
        如果需要的话,会在实例化对象之前执行
    3、MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(mbd, beanType, beanName)
        在对象实例化完毕 初始化之前执行
    4、InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)
        在bean创建完毕初始化之前执行
    5、InstantiationAwareBeanPostProcessor.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName)
        在bean的property属性注入完毕 向bean中设置属性之前执行
    6、BeanPostProcessor.postProcessBeforeInitialization(result, beanName)
        在bean初始化(自定义init或者是实现了InitializingBean.afterPropertiesSet())之前执行
    7、BeanPostProcessor.postProcessAfterInitialization(result, beanName)
        在bean初始化(自定义init或者是实现了InitializingBean.afterPropertiesSet())之后执行
    8、其中DestructionAwareBeanPostProcessor方法的postProcessBeforeDestruction(Object bean, String beanName)会在销毁对象前执行


    DestructionAwareBeanPostProcessor 中的requiresDestruction(Object bean)是用来判断是否属于当前processor处理的bean
    SmartInstantiationAwareBeanPostProcessor中的predictBeanType(Class<?> beanClass, String beanName)是用来预判类型的
    SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference(exposedObject, beanName)
        这个方法仅仅是在这一步是作为一个ObjectFactory封装起来放到singletonFactories中的,
        仅在并发情况下 刚好在当前对象设置进去,而另一个bean创建需要getBean获取时才会立即执行
        因此这一步的顺序是不一定的,有可能永远不会执行(无并发循坏依赖对象创建的场景)
        可能在3之后对象实例化完毕执行addSingleton(beanName, singletonObject);之前执行到
    因此这三个方法没有严格的顺序意义

  • 相关阅读:
    【Linux】linux中很有用的指令(练习)
    【C 标准库】<string.h>
    【Linux网络编程】使用GDB调试程序
    【LINUX网络编程】Makefile文件
    【UNIX网络编程】TCP客户/服务器程序示例
    【UNIX网络编程】基本TCP套接字编程
    pyQt5新手教程 (二)通过jupyter开始你的旅程-编写一个空白窗口
    pyQt5新手教程 (一)通过anaconda安装pyqt包
    如何把没用的tplink4C68路由器连起来
    xcode10升级之后开始安装cocoapods
  • 原文地址:https://www.cnblogs.com/zhangjianbin/p/10059191.html
Copyright © 2020-2023  润新知