Spring依赖注入源码阅读笔记
Posted haoyoung
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring依赖注入源码阅读笔记相关的知识,希望对你有一定的参考价值。
一、调用栈
一次典型的Spring依赖注入的调用栈:
- DefaultListableBeanFactory:getBean()
- AbstractBeanFactory:doGetBean()
- AbstractAutowireCapableBeanFactory:createBean()
- AbstractAutowireCapableBeanFactory:createBeanInstance()
- SimpleInstantiationStategy:instantiate()
- AbstractAutowireCapableBeanFactory:populateBean()
- AbstractAutowireCapableBeanFactory:applyPropertyValues()
- BeanDefinitionValueResolver:resolveValueIfNecessary()
- BeanDefinitionValueResolver:resolveReference()
二、依赖注入过程
- getBean:依赖注入的入口,处理参数调用doGetBean()
- doGetBean:检查是否需要创建bean,并取得beanDefinition;
- 单例Bean的处理,从Singleton的缓存中能取到,那就不需要创建。查找缓存的过程:先从
singletonObjects
中查找;如果没有查找到,又是正在创建的bean,则从earlySingletonObjects
中查找;仍未查找到,则通过singletonFactories
取得。 - 原型模式Bean的循环依赖检测,如果检测到正在创建(在
prototypesCurrentlyInCreation
[threadLocal
]中存在),则抛出异常,因为此时,很有可能已经发生了循环依赖。 - 向上递归查找beanDefinition,当前BeanFactory中不存在该bean的定义,则向父beanFactory递归调用getBean,直到找到为止。
- 合并父BeanDefinition以取得RootBeanDefinition,如果获取到的bean definition是一个子bean definition,则getMergedLocalBeanDefinition将它与父bean definition合并成一个root bean definition
- RootBeanDefinition的合法性检测:是否
abstract
- bean定义中显式声明的dependsOn,先进行初始化(递归的):并注册依赖关系,如果检测到循环依赖,则抛出异常。
- 创建Bean的辅助处理
- 单例bean:
singletonObjects
上锁- 把beanName加入到
singletonsCurrentlyInCreation
中 - 创建Bean
- 从
singletonsCurrentlyInCreation
中移除beanName - 解除
singletonObjects
锁定 - 如果过程中创建了一个实例,将它放入
singletonObjects
、registeredSingletons
,并从singletonFactories
、earlySingletonObjects
中移除 - 如果过程中发生了异常,将它从
singletonObjects
、registeredSingletons
、singletonFactories
、earlySingletonObjects
中移除 - 处理
FactoryBean
- 原型模式bean:
- 向
prototypesCurrentlyInCreation
中加入beanName - 创建Bean
- 从
prototypesCurrentlyInCreation
中移除beanName - 处理
FactoryBean
- 向
- 其余scope的bean处理:
- 检测scope是否存在
- 调用scope.get()方法,并传入getObject()回调。回调中的处理,与prototype下基本一致。
- 处理
FactoryBean
- 单例bean:
- 处理返回数据类型,检测是否可转为requiredType
- 单例Bean的处理,从Singleton的缓存中能取到,那就不需要创建。查找缓存的过程:先从
- createBean:创建出一个bean实例,初始化该实例,调用postprocessors等
- 解析出Class类型,即解析出一个Class<?>,赋到rootBeanDefinition中。但不能直接复制,需要拷贝出一个新的rootBeanDefinition,因为mergedBeanDefinition是共享的,可能有动态解析的class类型,直接赋值可能会有问题。
- 预处理重写方法,检测重写的方法是否存在,并判断是否是overload。
- 调用一遍postprocessors调用
InstantiationAwareBeanPostProcessor
的postProcessBeforeInstantiation
,这里有可能会返回一个bean的代理。如果返回了bean的代理,那么它将直接执行beanProcessor的postProcessAfterInitialization方法,并返回。 - 调用钩子方法doCreateBean
- doCreateBean
- 从缓存中移除同名bean从
factoryBeanInstanceCache
中移除同名bean - 创建Bean实例 createBeanInstance
- 调用一遍postprocessors调用
MergedBeanDefinitionPostProcessor
的postProcessMergedBeanDefinition
- Singleton循环依赖的处理:提前将刚创建的实例(未初始化的),放入缓存 如果是Singleton Bean并允许循环依赖,则将刚创建好的实例,放入
singletonFactories
与registeredSingletons
中,并从earlySingletonObjects
中将同名bean移除 - Bean初始化 populateBean,用bean definition中的property values初始化得到的bean实例
- 执行Spring扩展的初始化 initializeBean
invokeAwareMethods
如果bean实现了Aware的一些子接口,如BeanNameAware,则将相应的属性set到bean中- 调用一遍postprocessors 调用BeanPostProcessor的postProcessBeforeInitialization方法
invokeInitMethods
- 如果bean实现了
InitializingBean
接口,执行afterPropertiesSet()回调 - 如果在bean definition中显式自定义了init-method,则会执行一次initMethod回调(通过反射调用)
- 如果bean实现了
- 调用一遍postprocessors 调用BeanPostProcessor的postProcessAfterInitialization方法
- 注册bean销毁方法回调
- 从缓存中移除同名bean从
- createBeanInstance:使用不同的策略,创建bean实例
- 工厂方法 : 如果在bean definition中显式声明了factory-mothod,则调用工厂方法创建实例。
- 构造函数 : 选择合适的构造函数实例化
- CGLIB : 利用CGLIB实例化
- populateBean
- 取得bean definition的property values
- 调用一遍postprocessors调用
InstantiationAwareBeanPostProcessor
的postProcessAfterInstantiation
方法 - 处理autowire的注入
autowireByName
或autowireByType
- 调用一遍postprocessors调用
InstantiationAwareBeanPostProcessor
的postProcessPropertyValues
方法 - 对属性进行注入 applyPropertyValues,属性值注入,解析出运行时该bean factory中其他bean的引用。
- 获取BeanDefinitionValueResolver。
- 创建一个新的PropertyValue的list,作为存放解析后的PropertyValue的容器。必须是深拷贝的,否则会修改到原bean definition中的property values。
- 解析property value:resolveValueIfNecessary()
针对不同类型的value对象,有不同的convert方式,如value是RuntimeBeanReference类型的,递归调用getBean方法,获取bean。 - 用BeanWrapper的setPropertyValues方法,批量为bean的属性赋值。最终是调用bean的setXXX()方法赋值。
三、postprocessors及关键方法执行顺序
- 【
InstantiationAwareBeanPostProcessor
】postProcessBeforeInstantiation()
- createBeanInstance
- 【
MergedBeanDefinitionPostProcessor
】postProcessMergedBeanDefinition()
- 【
InstantiationAwareBeanPostProcessor
】postProcessAfterInstantiation()
- autowireByName;autowireByType
- 【
InstantiationAwareBeanPostProcessor
】postProcessPropertyValues()
- applyPropertyValues
- 【
BeanPostProcessor
】postProcessPropertyValues()
- 【
InstantiationAwareBeanPostProcessor
】postProcessBeforeInitialization()
- invokeInitMethods
- 【
InstantiationAwareBeanPostProcessor
】postProcessAfterInitialization()
以上是关于Spring依赖注入源码阅读笔记的主要内容,如果未能解决你的问题,请参考以下文章
初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段
初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段
spring练习,在Eclipse搭建的Spring开发环境中,使用set注入方式,实现对象的依赖关系,通过ClassPathXmlApplicationContext实体类获取Bean对象(代码片段