Spring的BeanPostProcessor后置处理器与bean的生命周期
前言
本文将把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的生命周期的更多相关文章
- Spring之BeanPostProcessor(后置处理器)介绍
为了弄清楚Spring框架,我们需要分别弄清楚相关核心接口的作用,本文来介绍下BeanPostProcessor接口 BeanPostProcessor 该接口我们也叫后置处理器,作用是在Be ...
- Spring点滴五:Spring中的后置处理器BeanPostProcessor讲解
BeanPostProcessor接口作用: 如果我们想在Spring容器中完成bean实例化.配置以及其他初始化方法前后要添加一些自己逻辑处理.我们需要定义一个或多个BeanPostProcesso ...
- 【Spring注解驱动开发】关于BeanPostProcessor后置处理器,你了解多少?
写在前面 有些小伙伴问我,学习Spring是不是不用学习到这么细节的程度啊?感觉这些细节的部分在实际工作中使用不到啊,我到底需不需要学习到这么细节的程度呢?我的答案是:有必要学习到这么细节的程度,而且 ...
- spring学习四:Spring中的后置处理器BeanPostProcessor
BeanPostProcessor接口作用: 如果我们想在Spring容器中完成bean实例化.配置以及其他初始化方法前后要添加一些自己逻辑处理.我们需要定义一个或多个BeanPostProcesso ...
- Spring Ioc源码分析系列--Ioc容器注册BeanPostProcessor后置处理器以及事件消息处理
Spring Ioc源码分析系列--Ioc容器注册BeanPostProcessor后置处理器以及事件消息处理 前言 上一篇分析了BeanFactoryPostProcessor的作用,那么这一篇继续 ...
- spring利用后置处理器初始化bean属性
spring利用后置处理器初始化bean属性 参考:http://blog.csdn.net/heyutao007/article/details/50326793 @Configurable @En ...
- BeanPostProcessor后置处理器原理以及ApplicationListener原理
BeanPostProcessor:bean后置处理器,bean创建对象初始化前后进行拦截工作的 1.BeanFactoryPostProcessor:BeanFactory的后置处理器; 在Bean ...
- Spring 如何保证后置处理器的执行顺序 - OrderComparator
Spring 如何保证后置处理器的执行顺序 - OrderComparator Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.htm ...
- Spring第三天,详解Bean的生命周期,学会后让面试官无话可说!
点击下方链接回顾往期 不要再说不会Spring了!Spring第一天,学会进大厂! Spring第二天,你必须知道容器注册组件的几种方式!学废它吊打面试官! 今天讲解Spring中Bean的生命周期. ...
随机推荐
- GP-荧光免疫分析仪SDK 协议
近期,闲来无事,得到一款GP的poct设备研究了下,该设备型号:Getein1100 ,串口进行通信,但是串口连接有所限制,于是找到一款数传模块,将串口转网口,使用pc进行通信抓包分析,如下: 在此可 ...
- pytorch bert 源码解读
https://daiwk.github.io/posts/nlp-bert.html 目录 概述 BERT 模型架构 Input Representation Pre-training Tasks ...
- day5_python之协程函数
一.yield 1:把函数的执行结果封装好__iter__和__next__,即得到一个迭代器2:与return功能类似,都可以返回值,但不同的是,return只能返回一次值,而yield可以返回多次 ...
- C. Tokitsukaze and Duel 前缀维护
枚举每一个连续的K的第一个位置,如果是先手胜利,那么前[1 , i-1 ]和[ i+k , n ]区间要么全是0,要么全是1 如果能够平局,那么肯定是[1,i-1],以及[ i+k , n]中有两种情 ...
- @NOI模拟2017.06.30 - T3@ Right
目录 @description@ @solution@ @part - 1@ @part - 2@ @accepted code@ @details@ @description@ JOHNKRAM 和 ...
- Android 隐藏EditText的焦点
在页面的开发过程中,我们可能会遇到这样的情况,打开某个页面(Activity)时,如果该页面中有EditText组建,则会自动弹出软键盘(因为该EditText自动获取焦点了),这样很容易影响用户体验 ...
- 【Learning Notes】线性链条件随机场(CRF)原理及实现
1. 概述条件随机场(Conditional Random Field, CRF)是概率图模型(Probabilistic Graphical Model)与区分性分类( Discriminative ...
- origin/HEAD -> origin/master 这个分支是干嘛的啊
➜ sso git:(master) ✗ git branch -r origin/4.0 origin/HEAD -> origin/master origin/master origin/H ...
- Python--day61--Django ORM单表操作之展示用户列表
user_list.html views.py 项目的urls.py文件
- H3C 配置基本ACL