前言

本文将把Spring在Bean的生命周期中涉及到的后置处理器一一梳理出来,并简要说一下功能,至于每个后置处理器在实际扩展中的用处,还要后续慢慢探索总结。

正文

下面一步步跟进探寻那些后置处理器们。首先进入AbstractApplicationContext类中的refresh方法,继续追踪至此模板方法中的finishBeanFactoryInitialization方法,然后点进beanFactory.preInstantiateSingletons()方法,进入DefaultListableBeanFactory类中,点进getBean方法,继续点击doGetBean方法,它是获取bean的核心方法,但我们只关注里面lambda表达式中的createBean方法,点之进入AbstractAutowireCapableBeanFactory#createBean方法,逐渐逼近无知兽。

第一处

在createBean方法的resolveBeforeInstantiation方法中,遇见第一处后置处理器的调用,而且一次调了两种,分别是:InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation和

BeanPostProcessor.postProcessAfterInitialization。如下截图所示:

此处如果before的方法返回的bean不为null, 方法返回之后在createBean方法中就不会往下走了(即后续的2-8处理器都不走)而是直接返回。

额外说一下Spring的使用实例。如果bean中有切面类,那么会调用AbstractAutoProxyCreator#postProcessBeforeInstantiation中的实现逻辑,在此方法中将切面类加入advisedBeans中,这样后续切面会自动忽略对advisedBeans中对象的拦截。

第二处

进入createBean中的doCreateBean方法,在createBeanInstance方法中调用了determineConstructorsFromBeanPostProcessors方法,里面是第二处后置处理器的调用:SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors。截图如下所示,此处后置处理器用于推断构造方法,默认调用的实现类是AutowiredAnnotationBeanPostProcessor。

 第三处

回到doCreateBean方法,继续往下看applyMergedBeanDefinitionPostProcessors方法,找到第三处后置处理器的调用:MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition。截图如下所示:

 第四处

在doCreateBean中继续往下找,getEarlyBeanReference方法中找到第四处调用:SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference。此处用于解决循环依赖,截图如下:

第五处

继续往下,进入populateBean方法,在此方法中有两处调用,第五处:InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation。返回布尔类型,用于判断是不是需要属性填充,如果返回false则直接从populateBean中返回,不再执行第6/7/8处。

 第六处

第六处调用了两个方法:InstantiationAwareBeanPostProcessor.postProcessProperties和InstantiationAwareBeanPostProcessor.postProcessPropertyValues。此处用于做属性填充,截图如下:

 第七处

回到doCreateBean中继续往下,进入initializeBean方法,此方法中也有两处调用,在applyBeanPostProcessorsBeforeInitialization中调用了第七处:BeanPostProcessor.postProcessBeforeInitialization。

调用的是通常意义上BeanPostProcessor的before方法

 第八处

在applyBeanPostProcessorsAfterInitialization中调用了第八处:BeanPostProcessor.postProcessAfterInitialization。调用的是通常意义上BeanPostProcessor的after方法

Spring的切面就是基于此方法进行的,调用的实现方法是AbstractAutoProxyCreator#postProcessAfterInitialization。它会先将切面类放入advisedBeans中,标记为true,表示需要用切面拦截。然后调用AbstractAutoProxyCreator#createProxy方法生成代理。

第九处

第九处是在执行AbstractApplicationContext#close方法销毁bean时触发的,最终调用到的是DisposableBeanAdapter#destroy,在此方法中调用了:DestructionAwareBeanPostProcessor.postProcessBeforeDestruction。用于在销毁bean之前做操作。为什么DestructionAwareBeanPostProcessor中没有after方法?因为执行after的时候所有bean都没了,Spring认为你也没必要做什么扩展了。

小结

以上就是Spring的bean声明周期内经手的9处后置处理器调用,共涉及到5个接口,本文只是简要说明了其作用,其真实的使用场景很多,需要后续慢慢摸索。

Spring的BeanPostProcessor后置处理器与bean的生命周期的更多相关文章

  1. Spring之BeanPostProcessor(后置处理器)介绍

      为了弄清楚Spring框架,我们需要分别弄清楚相关核心接口的作用,本文来介绍下BeanPostProcessor接口 BeanPostProcessor   该接口我们也叫后置处理器,作用是在Be ...

  2. Spring点滴五:Spring中的后置处理器BeanPostProcessor讲解

    BeanPostProcessor接口作用: 如果我们想在Spring容器中完成bean实例化.配置以及其他初始化方法前后要添加一些自己逻辑处理.我们需要定义一个或多个BeanPostProcesso ...

  3. 【Spring注解驱动开发】关于BeanPostProcessor后置处理器,你了解多少?

    写在前面 有些小伙伴问我,学习Spring是不是不用学习到这么细节的程度啊?感觉这些细节的部分在实际工作中使用不到啊,我到底需不需要学习到这么细节的程度呢?我的答案是:有必要学习到这么细节的程度,而且 ...

  4. spring学习四:Spring中的后置处理器BeanPostProcessor

    BeanPostProcessor接口作用: 如果我们想在Spring容器中完成bean实例化.配置以及其他初始化方法前后要添加一些自己逻辑处理.我们需要定义一个或多个BeanPostProcesso ...

  5. Spring Ioc源码分析系列--Ioc容器注册BeanPostProcessor后置处理器以及事件消息处理

    Spring Ioc源码分析系列--Ioc容器注册BeanPostProcessor后置处理器以及事件消息处理 前言 上一篇分析了BeanFactoryPostProcessor的作用,那么这一篇继续 ...

  6. spring利用后置处理器初始化bean属性

    spring利用后置处理器初始化bean属性 参考:http://blog.csdn.net/heyutao007/article/details/50326793 @Configurable @En ...

  7. BeanPostProcessor后置处理器原理以及ApplicationListener原理

    BeanPostProcessor:bean后置处理器,bean创建对象初始化前后进行拦截工作的 1.BeanFactoryPostProcessor:BeanFactory的后置处理器; 在Bean ...

  8. Spring 如何保证后置处理器的执行顺序 - OrderComparator

    Spring 如何保证后置处理器的执行顺序 - OrderComparator Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.htm ...

  9. Spring第三天,详解Bean的生命周期,学会后让面试官无话可说!

    点击下方链接回顾往期 不要再说不会Spring了!Spring第一天,学会进大厂! Spring第二天,你必须知道容器注册组件的几种方式!学废它吊打面试官! 今天讲解Spring中Bean的生命周期. ...

随机推荐

  1. mysql 中 DATE_ADD函数和 DATE_SUB函数用法

    mysql 中 DATE_ADD(date,INTERVAL expr type) 和 DATE_SUB(date,INTERVAL expr type) 这些函数执行日期运算. date 是一个 D ...

  2. 在VirtualBox下安装linux操作系统

    目标:在linux服务器上部署Java开发的网站 工具 VirtualBox-4.3.8:下载后安装. linux系统镜像: Centos国内镜像文件下载地址: http://centos.ustc. ...

  3. element表格多选实现单选

    9.element多选表格实现单选 userChoose(selection, row) { console.log(selection,'selection') console.log(row,'r ...

  4. wpf 登录时显示状态动态图

    下面的示例演示了如何在登录过程时,界面上显示状态图标,登录完成后隐藏图标: public partial class MainWindow : Window { public MainWindow() ...

  5. Python--day66--模板语言之自定义mysimpletag

  6. docker swarm搭建tidb踩坑日记

    背景 公司新项目数据量翻了一倍,每天上亿数据量的读写,传统的单库单表已经满足不了目前的需求,得考虑下分布式存储了.那用啥呢,之前有考虑用到mycat,但是一进官网,一股山寨气息扑面而来,技术群进群还收 ...

  7. poj 3275 "Ranking the Cows"(DFS or Floyd+bitset<>)

    传送门 题意: 农场主 FJ 有 n 头奶牛,现在给你 m 对关系(x,y)表示奶牛x的产奶速率高于奶牛y: FJ 想按照奶牛的产奶速率由高到低排列这些奶牛,但是这 m 对关系可能不能精确确定这 n ...

  8. D3.js力导向图(适用于其他类型图)中后添加元素遮盖已有元素的问题解决

    上一篇说了在D3.js中动态增加节点及连线的一种实现方式,但是有后添加元素遮盖原节点的现象,这一篇说一下出现这个现象的解决办法. 在D3.js中后添加的元素是会遮盖先添加的元素的,同时还有一个设定:后 ...

  9. C++ 图片格式转化和压缩

    在做人脸识别底库图片导入的时候,需要支持主流的图片的格式,如jpeg.bmp.png等格式.所以需要对图片进行格式转化.图片过大的话,还有进行缩放等.本文介绍的是利用cximage开源库,来进行对图片 ...

  10. CodeForces - 922D Robot Vacuum Cleaner (贪心)

    Pushok the dog has been chasing Imp for a few hours already. Fortunately, Imp knows that Pushok is a ...