写点什么

spring 篇之属性注入

作者:邱学喆
  • 2022 年 7 月 09 日
  • 本文字数:1612 字

    阅读完需:约 5 分钟

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 容器中查找目标对象的逻辑是整个属性注入过程中最复杂的;现在单独来进行介绍;

查找目标对象的接口如下:

//AutowireCapableBeanFactory.java/** * descriptor: 依赖的描述符,这里主要记录属性、方法、构造方法等信息 * requestingBeanName: 实例对象名称 * autowiredBeanNames: 注入对象的实例名称,这个是有方法内部自行填充 * typeConverter:类型转换 */	@Nullable	Object resolveDependency(DependencyDescriptor descriptor,                            @Nullable String requestingBeanName,                           @Nullable Set<String> autowiredBeanNames,                            @Nullable TypeConverter typeConverter) throws BeansException;
复制代码

其主要的流程图如下:


其中 findAutowireCandidates 方法的流程图如下:

而【决定最终的候选人】逻辑就比较简单,简单介绍:

##DefaultListableBeanFactory.determineAutowireCandidate:primary > 高优先级 > 解析后的依赖对象
复制代码


发布于: 刚刚阅读数: 3
用户头像

邱学喆

关注

计算机原理的深度解读,源码分析。 2018.08.26 加入

在IT领域keep Learning。要知其然,也要知其所以然。原理的爱好,源码的阅读。输出我对原理以及源码解读的理解。个人的仓库:https://gitee.com/Michael_Chan

评论

发布
暂无评论
spring篇之属性注入_spring_邱学喆_InfoQ写作社区