@Autowired是什么
@Autowired 注解由 Spring 的 org.springframework.beans.factory.annotation.Autowired 类定义, 直译过来就是自动注入的意思。
@Autowired的定义如下:
@Autowired 的使用场景
1.字段注入
将 @Autowired 直接应用于类的成员变量上。Spring 容器会自动为这些变量找到与其类型匹配的 Bean 实例,并进行注入。
2.构造器注入
将 @Autowired 应用于类的构造函数上。
Spring 容器会自动解析构造函数的参数类型,并为这些参数找到与其类型匹配的 Bean 实例,然后注入到构造函数中。
3.方法注入
将 @Autowired 应用于类的方法上。
当类实例化时,Spring 容器会自动解析这些方法的参数类型,并为这些参数找到与其类型匹配的 Bean 实例,然后调用这些方法并注入参数。
需要注意的是,通过 @Autowired 注解实现依赖注入时,如果在 Spring 容器中找不到与某个依赖类型匹配的 Bean 实例(或者找到多个,但没有明确的优先级),那么 Spring 将抛出异常。
除非将该注解的 required 属性设置为 false,这样在找不到匹配的 Bean 时,框架将不会抛出异常。
@Autowired是如何工作的
在 Spring 中,AutowiredAnnotationBeanPostProcessor (AABP) 负责处理带有 @Autowired 注解的成员变量、Setter 方法。
以下是 AABP 解析 @Autowired 的完整代码调用流程:
当 Spring 容器实例化一个 Bean 时,会创建相应的 BeanDefinition 对象。BeanDefinition 包含了关于 Bean 的所有元数据信息。
在容器实例化、配置和初始化 Bean 的过程中,它会调用 AABP 的 postProcessMergedBeanDefinition 方法,以收集与依赖注入相关的元数据。
findAutowiringMetadata 方法会查找 Bean 的所有@Autowired 注解相关的元数据,并获取 InjectionMetadata 对象, 如果该对象尚不存在,会创建一个新的对象。
上面的代码中,我在关键位置添加了注释,老铁们可以仔细看一下,上述代码的主要作用就是找到一个类中:
- 添加了@Autowired的属性信息,用 AutowiredFieldElement进行表示。
- 添加了 @Autowired 的方法信息,用AutowiredMethodElement进行表示。
当依赖注入需要发生时,容器会调用 AABP 的 postProcessProperties 方法。
该方法中会调用 InjectionMetadata 的 inject 方法来实际注入 @Autowired 注解的成员变量、成员方法:
最后,通过执行 AutowiredFieldElement 和 AutowiredMethodElement 的 inject 方法来实际注入属性值和方法参数。
AutowiredFieldElement 的 inject 方法实现如下:
AutowiredMethodElement 的 inject 方法的实现如下:
通过以上流程,AutowiredAnnotationBeanPostProcessor 将解析并注入带有 @Autowired 注解的成员变量、方法。