1、BeanPostProcessor的五大接口

一共有11个回调方法

1.1.BeanPostProcessor

关于对象初始化前后的回调。
public interface BeanPostProcessor {//该方法在bean已经实例化并属性注入完毕,在执行初始化方法(afterPropertiesSet或自定义init方法)之前调用@Nullabledefault Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}//在执行初始化方法(afterPropertiesSet或自定义init方法)之后调用@Nullabledefault Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}
}

1.2.InstantiationAwareBeanPostProcessor

关于对象实例化前后以及实例化后设置propertyValues的回调
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {//这个方法用来在对象实例化前直接返回一个对象(如代理对象)来代替通过内置的实例化流程创建对象;@Nullabledefault 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等就是根据这个回调来实现最终注入依赖的属性的。@Nullabledefault PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {return pvs;}
}

1.3.SmartInstantiationAwareBeanPostProcessor

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

1.4.MergedBeanDefinitionPostProcessor

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

1.5.DestructionAwareBeanPostProcessor

关于处理对象销毁的前置回调
应用实例:ApplicationListenerDetector,这个类是用来注册ApplicationListener实例的,而如果销毁一个对象,不接触这里的引用会导致无法进行回收,因此在销毁对象时,会判断如果是ApplicationListener要执行从监听器列表中移除掉。
public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {//这里实现销毁对象的逻辑void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;//判断是否需要处理这个对象的销毁default boolean requiresDestruction(Object bean) {return true;}
}

2.关于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);之前执行到
因此这三个方法没有严格的顺序意义

3.验证执行顺序

@Configuration
public class Application {public static void main(String[] args) {AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Application.class);applicationContext.registerBeanDefinition("demoBean", new RootBeanDefinition(DemoBean.class));applicationContext.getBean("demoBean");applicationContext.start();applicationContext.destroy();}@Beanpublic BeanPostProcessor fullyPostProcessor() {return new FullyBeanPostProcessor();}public static class DemoBean {}@Orderpublic class FullyBeanPostProcessor implements BeanPostProcessor,InstantiationAwareBeanPostProcessor,SmartInstantiationAwareBeanPostProcessor,MergedBeanDefinitionPostProcessor,DestructionAwareBeanPostProcessor {@Overridepublic Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {if (beanClass == DemoBean.class) {System.out.println("1 --> InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(beanClass, beanName)");}return null;}@Overridepublic Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {if (beanClass == DemoBean.class) {System.out.println("2 --> SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors(beanClass, beanName)");}return null;}@Overridepublic void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {if (beanType == DemoBean.class) {System.out.println("3 --> MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(mbd, beanType, beanName)");}}@Overridepublic boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {if (bean instanceof DemoBean) {System.out.println("4 --> InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)");}return true;}@Overridepublic PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {if (bean instanceof DemoBean) {System.out.println("5 --> InstantiationAwareBeanPostProcessor.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName)");}return pvs;}@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof DemoBean) {System.out.println("6 --> BeanPostProcessor.postProcessBeforeInitialization(result, beanName)");}return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof DemoBean) {System.out.println("7 --> BeanPostProcessor.postProcessAfterInitialization(result, beanName)");}return bean;}@Overridepublic void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {if (bean instanceof DemoBean) {System.out.println("8 --> DestructionAwareBeanPostProcessor.postProcessBeforeDestruction(Object bean, String beanName)");}}@Overridepublic Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {return null;}@Overridepublic Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {return bean;}}
}
最终输出结果:1 --> InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(beanClass, beanName)2 --> SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors(beanClass, beanName)3 --> MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(mbd, beanType, beanName)4 --> InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)5 --> InstantiationAwareBeanPostProcessor.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName)6 --> BeanPostProcessor.postProcessBeforeInitialization(result, beanName)7 --> BeanPostProcessor.postProcessAfterInitialization(result, beanName)8 --> DestructionAwareBeanPostProcessor.postProcessBeforeDestruction(Object bean, String beanName)

关于几个BeanPostProcessor各个回调的时机相关推荐

  1. Spring源码学习:BeanPostProcessor注册和执行时机

    目录 前言 1 BeanPostProcessors作用 2 源码分析 2.1 BeanPostProcessors注册时机 2.1.1 注册beanPostProcessorChecker 2.1. ...

  2. 面试题:函数回调机制、异步函数回调机制图例详解 没毛用

    函数回调机制,一种双向调用思想,简单来说就是,如下图所示: 在层次一中的方法一(函数)调用层次二中的方法,并传入函数二的地址,而这个被调用的方法又会调用层次一中的方法,这个最后被调用的方法二就是回调方 ...

  3. java回调机制及其实现(转)

    1. 什么是回调函数 回调函数,顾名思义,用于回调的函数.回调函数只是一个功能片段,由用户按照回调函数调用约定来实现的一个函数.回调函数是一个工作流的一部分,由工作流来决定函数的调用(回调)时机.回调 ...

  4. 【转】回调函数,函数指针与函数对象

    原文出处:http://shudingbo.spaces.live.com/blog/cns!C33400475B08F157!423.entry?wa=wsignin1.0&sa=24651 ...

  5. 【小家Spring】注意BeanPostProcessor启动时对依赖Bean的“误伤”陷阱(is not eligible for getting processed by all...)

    每篇一句 祝大家五一国际劳动节快乐~你是在快乐的撸码,还是在快乐的浪呢? 本文已被https://yourbatman.cn收录:程序员专用网盘https://wangpan.yourbatman.c ...

  6. 基于回调的观察者模式

    文章目录 回调机制的简单的理解: 比较经典的回调方式: 示例 基于监听的事件处理 回调的简单理解 同步回调 异步回调函数 Java回调机制进阶 回调进阶(基于回调的"观察者"模式的 ...

  7. Android-UI-绘制请求与绘制时机

    先来看一个高频面试题: 介绍一下 Android 屏幕显示原理,开发编写的 View 控件,是怎么变成屏幕上显示的图像的? 这个问题该怎么回答呢? 一个思路是先整体串讲,宏观的把Android UI ...

  8. Java 回调函数作用和使用场景

    1. 什么是回调函数  回调函数(callback Function),顾名思义,用于回调的函数. 回调函数只是一个功能片段,由用户按照回调函数调用约定来实现的一个函数.回调函数是一个工作流的一部分, ...

  9. Java回调机制研究

    1. 什么是回调函数 回调函数,顾名思义,用于回调的函数.回调函数只是一个功能片段,由用户按照回调函数调用约定来实现的一个函数.回调函数是一个工作流的一部分,由工作流来决定函数的调用(回调)时机.回调 ...

最新文章

  1. c语言程序设计课件数组,第五章 数组_《C语言程序设计(Visual C++ 6.0环境)》电子教案_ppt_大学课件预览_高等教育资讯网...
  2. 免费!!3天,吃透JVM!(限时领)
  3. xhtmlrenderer 将html转换成pdf,完美css,带图片,手动分页,解决内容断开的问题
  4. 如何使用数据库SCHEDULER来执行清归档脚本
  5. Web网站架构设计(转)
  6. [翻译] VLDContextSheet
  7. 电气工程师学python_Python 在电气工程及其自动化上有哪些应用?
  8. 使用Apache Cassandra设置一个SpringData项目
  9. 不要在循环,条件或嵌套函数中调用 Hook
  10. 剑指offer——面试题54:表示数值的字符串
  11. LINUX加载库时与WINDOWS有何不同
  12. Java出现No enclosing instance of type E is accessible. Must qualify the allocation with an enclosing
  13. linux迅雷下载命令,命令行也强大之下载迅雷资源的方法
  14. 利用VS的代码优化和openmp并行计算提高程序运行速度
  15. Unity3D插件大全
  16. java获取法定节假日_java 获取n个工作日后的日期(包含法定节假日、双休日、节后补班)...
  17. EOS DApp 已成黑客提款机
  18. cut命令的详细用法
  19. 32位64位Eclipse和jdk对应关系说明【初学者适用】
  20. pycharm安装sklearn失败解决方法

热门文章

  1. 列举php magic方法,如何在PHP中實現__isset()魔術方法?
  2. asp 退出登录修改cookie能进入后台_某logCMS的代码审计:越权到后台getshell
  3. codeblocks 编译java_在CodeBlocks中发布编译程序
  4. java第三次实验作业
  5. centos安装php
  6. .NET笔试题(关于迭代的:遍历XML中的FileName)
  7. 大道至简 第二章 读后随笔
  8. android 布局中的单位及分辨率自解
  9. Quote Form OnLoad Implement Add Leftnav, count Activities
  10. Software Project Management之EVM问题的求解