总文档 :文章目录
Github : github.com/black-ant
一 . 前言
上一篇说了盘点 SpringIOC : Bean 创建主流程 , 这一篇把第二个主要环节 属性注入
还是来看一个很常见的图 , 来源于 @ topjava.cn/article/139…
1.1 这篇文档的属性注入到底包含了哪些内容 ?
PS :无意中发现这篇文章不能只局限于 populateBean , 所以后续会在这个小章节陆续完善如下信息 , 感兴趣的可以持续关注 !
Bean 的属性处理主要范围为为Bean 进行注入 ,按照我们一般了解的 , Bean 注入主要包括三种注入方式 : 属性 / 构造器 / setter
- 方式一 : 通过构造器 @Autowired 主流程
- 方式二 : 通过属性上 @Autowired 主流程
- 方式三 : 通过 setter 方式 @Autowired 主流程
方式一 : 通过构造器 @Autowired 主流程
1 | java复制代码@Autowired |
1 | java复制代码//上图是一张 doCreateBean 方法中 , 执行 createBeanInstance(beanName, mbd, args) 的属性图 |
方式二 : 通过属性上 @Autowired 主流程
上图可以看到 , createBeanInstance 后 2个属性均未开始加载 , 但是我们又知道 , 属性的注入是在 initializeBean前完成 , 以保证初始化方法可用.
1 | java复制代码// 在处理 populateBean 时 , 会对 InstantiationAwareBeanPostProcessor 进行处理 , 其中主要有这些 |
方式三 : setter
1 | java复制代码//方式三和方式二类型 , 处理的 PostProcessor 主要为 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor |
二 . 属性注入流程
区别于上面的 autowired , populateBean 还主要处理了什么?
为了更好的理解流程 , 这里要区分一下 , 除了 autowired 注入属性外 , populateBean 中还有一个重要的概念叫 PropertyValues
1 | java复制代码TODO : 这一块有大问题 , 其来源始终没有弄懂, 查阅资料大多数也是一笔带过 |
我们来好好的看一下 属性注入的流程
2.1 属性注入的入口
1 | java复制代码C- AbstractAutowireCapableBeanFactory |
2.2 属性注入主流程
属性的注入主流程是在 doCreateBean 中 , 回忆循环依赖的相关概念 ,在调用populateBean 之前 , 已经产生了一个对象 , 该对象未完成相关的属性注入
先来看一下传入的属性
populateBean(beanName, mbd, instanceWrapper);
PS:属性注入是在 InitializingBean 之前 , 所以相关的初始化方法可以使用 @Autowired 对象 , 这个后续详细说说
属性注入 populateBean 逻辑
逻辑整体上分为7步 :
- Step 1 : BeanWrapper 空实例的处理 : 实例化之前要对空实例进行判断和处理
- Step 2 : BeanPostProcessors 处理
- Step 3 : 为 bean 注入属性
- Step 4 : 判断是否注册了 InstantiationAwareBeanPostProcessors 以及是否需要依赖检查
- Step 5 : BeanPostProcessor 处理 , 此处主要是 InstantiationAwareBeanPostProcessor 的处理
- Step 6 : 依赖检查
- Step 7 : applyPropertyValues(beanName, mbd, bw, pvs)
1 | java复制代码 |
PS:M173_30_3 MutablePropertyValues 的作用
允许简单的属性操作,并提供构造函数来支持从Map深度复制和构造
1 | java复制代码C190- MutablePropertyValues |
PS:M173_30_4 通过不同类型注入
1 | java复制代码C173- AbstractAutowireCapableBeanFactory |
M173_10 autowireByName 源码
1 | java复制代码protected void autowireByName( |
M173_11 autowireByType 源码
ps : 这里一开始案例太少 ,没看懂 , 回头翻了一下 死磕系列的笔记 , 终于搞清楚了
这一段参照死磕 IOC , 仅补充部分逻辑
1 | java复制代码protected void autowireByType( |
PS:M173_11_01 可以看到这里是 setter 方法
关于默认注入类型的问题
之前看资料的时候 , 一直都是说 AutoWired 默认使用 byType , 但是实际debug 中 ,发现并没有 , 在属性注入的时候 , 返回的类型为 0 , 即AUTOWIRE_NO , 其实这个是要分情况处理的:
1 | java复制代码 |
resolveDependency 详情
resolveDependency 方法主要被 autowireByType 调用 , 此外在 AutowiredAnnotationBeanPostProcessor 中也有所涉及
作用 : 针对此工厂中定义的bean解析指定的依赖项
1 | java复制代码public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName, |
PS:M173_30_5 InstantiationAwareBeanPostProcessor 结构
结构 : BeanPostProcessor的子接口
功能 : 添加了一个实例化之前的回调函数和一个实例化之后但在显式属性设置或自动装配发生之前的回调函数
常用 : 创建带有特殊target Source的代理(池化目标、延迟初始化目标等) , 实现额外的注入策略
特点 : 这个接口中 , 除了BeanPostProcessor默认的 postProcessBeforeInstantiation , postProcessAfterInstantiation 的方法外 , 还有一个额外的方法 postProcessProperties , postProcessPropertyValues
1 | java复制代码// public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor |
2.3 PropertyValue 和 applyPropertyValues 的作用
整个流程中 , 反复出现了一个属性 PropertyValue , 我们来看一下其中的前世今生
1 | java复制代码// M173_11 源代码 |
M173_15 applyPropertyValues 源代码
1 | java复制代码protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { |
总结
看起来挺长的 , 但是回头看了死磕系列感觉还有很多地方自己还没有看懂 , 后面有时间把这个坑填上
太晚了 , 比不过卷王们 ,洗洗睡了
附录
附录一 : M173_30 populateBean 核心代码
1 | java复制代码protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { |
附录二 : autowireConstructor 主方法 TODO
1 | java复制代码public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, |
附录三 : @Value 的注入时机
1 | java复制代码 |
本文转载自: 掘金