spring 篇之属性注入
一. 概述
在 spring 的 bean 的生命周期中,属性的注入是很复杂的一个逻辑。将其拆分出各个部分,进行逐一突破,后续有关基于 spring 的开发,那么就更加得心应手;
属性注入的核心代码,主要是在两处代码
AbstractAutowireCapableBeanFactory.populateBean 对这个对象进行属性的填充
AbstractAutowireCapableBeanFactory.initializeBean 这个是 spring 自身的特性,对某些特性接口进行属性注入,例如 BeanFactoryAware、InitializingBean 等接口;
二. 对象填充
populateBean 方法中关键逻辑,大体梳理如下:
接下来,会进行详细介绍:
autowireMode 自动模式,该字段有如下值:
AUTOWIRE_NO 不做任何处理;其是默认值
AUTOWIRE_BY_NAME 根据名称从 spring 容器中查找对应的实例对象,从而进行属性注入;
AUTOWIRE_BY_TYPE 根据类型来从 spring 容器中查找对应的实例对象,从而进行属性注入;
AUTOWIRE_CONSTRUCTOR 如果设置了该值,意味在实例对象时,会从目标类中寻找中优化的构造函数,从而进行创建对象;
AUTOWIRE_AUTODETECT 来自动检测具体自动模式;主要是根据目标类的构造函数中是否有入参;如果没有参数,则使用 AUTOWIRE_BY_TYPE ;否则使用 AUTOWIRE_CONSTRUCTOR
PVS 对象,主要是存放目标对象中的属性名以及对应的属性对象;具体的结构可以去查阅 MutablePropertyValues 类
遍历 spring 提供的前置处理器 InstantiationAwareBeanPostProcessor 来对目标对象进行属性注入;这里主要是有关键的几个常见的实例类
CommonAnnotationBeanPostProcessor 这个实现类主要对带有 @Resource 注解的属性以及方法进行操作(属性注入);
AutowiredAnnotationBeanPostProcessor 这个实现类主要是对带有 @Autowired、@Value、@Inject 的属性以及方法进行操作(属性注入)
dependencyCheck 依赖检测,如果发现属性值没有被初始化的,根据策略是忽略还是终止;该字段有如下值:
DEPENDENCY_CHECK_NONE 不用检测,其是默认值
DEPENDENCY_CHECK_OBJECTS 只检测引用对象
DEPENDENCY_CHECK_SIMPLE 只检测基本对象,如 int 等
DEPENDENCY_CHECK_ALL 检查所有的属性值
最后遍历 PVS 对象的属性值,通过 BeanWrapper 来进行属性注入;
CommonAnnotationBeanPostProcessor 和 CommonAnnotationBeanPostProcessor 对象的属性注入,都是遍历目标对象的属性字段以及方法,是否带有指定的注解。当带有时,则会通过包装成 InjectedElement 的子类(AutowiredFieldElement)等,最终再次包装成 InjectionMetadata 对象;交给 InjectionMetadata 对象,该对象主要的逻辑是带有缓存,以及从 spring 容器中查找目标对象,从而进行属性注入;
三. 初始化 Bean
针对 spring 提供的特定接口,对其进行方法调用,从而达到属性注入的效果;
这里主要有如下关键的接口
BeanFactoryAware 注入 spring 容器对象
InitializingBean 调用目标对象的方法,交给目标对象自己进行相关的初始化操作
调用 @Bean 注解中的 initMethod 指定的方法
四. 查找目标对象
上面的对象填充环节的,从 spring 容器中查找目标对象的逻辑是整个属性注入过程中最复杂的;现在单独来进行介绍;
查找目标对象的接口如下:
其主要的流程图如下:
其中 findAutowireCandidates 方法的流程图如下:
而【决定最终的候选人】逻辑就比较简单,简单介绍:
版权声明: 本文为 InfoQ 作者【邱学喆】的原创文章。
原文链接:【http://xie.infoq.cn/article/87223e59011780e74d66792b4】。文章转载请联系作者。
评论