Spring学习之@Autowireid
文章目录
注解说明
@Autowired 是Spring框架的核心注解,用于自动装载构造器、字段、set方法、配置方法上的依赖,它是 JSR-330 @Inject 注解的替代,支持配置 依赖是否必须
选项
属性说明
此注解只有一个属性 required
,默认为 true 表示待注入组件必须存在

注解注入规则说明
构造器注入
- 如果一个类声明了多个构造器且没有一个显式标注 @Autowired,则Spring会使用默认的构造方法进行装载
- 如果一个类只声明了一个构造器,不管有没有标注 @Autowired 注解它都会被直接使用
- 多参数可以配置多个required属性,对于可选注入,可以声明为 Java8 的Optional类型
字段注入
字段在构造器之后,配置方法注入之前进行自动注入
方法注入
方法注入不限制方法名与参数个数,所有参数会被Spring进行匹配注入
参数注入
目前只在 spring-test 模块中有效,其它地方使用会被忽略
数组/集合注入
Spring通过匹配数组/集合的值进行注入,Map的key必须为String类型,支持集合中元素的Order配置
不支持 BeanPostProcessor 或者 BeanFactoryPostProcessor
因为真实的注入动作发生在 BeanPostProcessor
阶段,所以不能在 BeanPostProcessor
或者 BeanFactoryPostProcessor
中使用此注解
源码阅读
在Spring中,处理 @Autowired 注解对应的类为 AutowiredAnnotationBeanPostProcessor ,又是一个Bean后置处理器

对于此类,需要关注其实现的两个接口类 MergedBeanDefinitionPostProcessor
(运行时合并Bean的定义回调接口)和 InstantiationAwareBeanPostProcessor
(在Bean实例化前后进行处理后置处理器)
- MergedBeanDefinitionPostProcessor 主要是为了在真正bean实例化前准备缓存的bean元数据
- InstantiationAwareBeanPostProcessor Bean实例化回调接口,通常用于为bean创建代理
测试代码
|
|
元数据收集
调用栈信息如下:
|
|
由调用栈信息可以发现此动作发生在 finishBeanFactoryInitialization()
阶段, 在doCreateBean方法中被调用

核心逻辑在 buildAutowiringMetadata()
方法中,此方法会循环遍历当前的类及其父类(一直到Object类为止),处理类中的字段与方法是否有需要自动装载的配置,如果有,则会将需要注入的元数据信息存放在 List<InjectionMetadata.InjectedElement> 中返回

在调用方 findAutowiringMetadata()
方法会将返回的元数据信息存入 injectionMetadataCache 中
AutowiredAnnotationBeanPostProcessor能处理哪些注解?

由其构造器逻辑可以发现, AutowiredAnnotationBeanPostProcessor
可以处理:
- @Autowired
- @Value
- @jakarta.inject.Inject
- @javax.inject.Inject
注入
自动装配的注入是由 AutowiredAnnotationBeanPostProcessor#postProcessProperties()
来处理(此方法会被AbstractAutowireCapableBeanFactory#populateBean调用),它会先调用 findAutowiringMetadata()
来查询要注入的元数据信息,查到后调用元数据实体InjectionMetadata的inject() 方法,在此方法会遍历当前InjectionMetadata的所有injectedElements元素进行注入操作


支持注入方式: 字段注入(AutowiredFieldElement)与方法注入(AutowiredMethodElement)
第一次由于没有缓存,则会调用 AutowiredFieldElement#resolveFieldValue()
方法(因为测试用例将注解写在了字段上),此方法会调用 DefaultListableBeanFactory#resolveDependency()
对需要注入的bean进行查找解析,找到后会将要注入的bean通过反射设置到当前Class对应字段上。真正的依赖bean解析工作是由 doResolveDependency()
来完成的。


doResolveDependency具体实现步骤:
- 使用快捷方式解析,因为实现直接返回null,则继续往下执行
- 解析@Value注解上预定义的值或者表达式,由于测试用例未配置,则继续执行
- 通过声明的依赖名称进行解析,对于要查找的依赖名称和类型进行判断,满足条件后,则通过调用 getBean() 方法获取依赖的Bean实例,获取成功后则调用 resolveInstance() 直接返回,否则继续执行
- 处理多bean,如集合、数组、Map
- 特定类型的集合bean匹配(收集装配),有则返回
- 直接使用bean定义匹配
- 如果匹配到了多个,确定一个,确定不了抛异常
- 对单个结果进行检验
本次用例的依赖解析会在第3步中查找完成并进行返回,对于第3步中一个合格的依赖bean需要满足条件如下:
- 类型匹配
- 是可以注入的候选者
- 没有被标注为fallback
- 不是primary冲突的bean
- 不是自引用
关联注解:
- @Primary
- @Qulifier
- @Order
- @Fallback
总结
@Autowired
是Spring框架的核心注解,用于自动注入依赖Bean,可实现对字段、构造器、方法的注入,支持集合类型方式注入。其实现类为 AutowiredAnnotationBeanPostProcessor
, Spring解析此注解发生在 refresh 操作的 finishBeanFactoryInitialization 阶段。注入分为两步:
- 收集:在构建实例(doCreateBean)时会调用
AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition()
方法来统一对merged bean 定义进行修改,具体实现为遍历当前类以及父类(到Object类为止),判断其定义的字段或者方法上是否标注了此注解,标注则记录其相应的注入信息。 - 注入:真正的注入发生在调用
AbstractAutowireCapableBeanFactory#populateBean()
,此方法会调用AutowiredAnnotationBeanPostProcessor#postProcessProperties()
查询收集的依赖的Bean信息,找到后进行注入,在注入过程中会对候选者进行一系列的条件筛选,满足条件则注入成功
整体流程涉及的核心类调用关系图