Beans 和依赖注入
相关源文件
本文档解释了 Spring 的控制反转 (IoC) 容器,重点关注 bean 管理和依赖注入机制,包括 `ApplicationContext`。它涵盖了 bean 如何通过 `BeanDefinition` 对象定义,由 `DefaultListableBeanFactory` 实例化,以及依赖项如何通过 `AutowiredAnnotationBeanPostProcessor` 和相关组件解析和注入。
Bean 容器的核心组件
Spring 的 IoC 容器围绕一系列类构建,这些类提供了日益复杂的 bean 管理功能。
Bean 工厂类层次结构
来源
关键实现类
DefaultListableBeanFactory
核心 bean 注册中心,维护 `beanDefinitionMap` 并通过 `resolveDependency()` 处理 bean 解析。
关键数据结构
- `beanDefinitionMap`:存储以 bean 名称为键的 `BeanDefinition` 对象
- `singletonObjects`:单例 bean 实例的缓存
- `resolvableDependencies`:用于编程注册依赖项的 Map
AbstractAutowireCapableBeanFactory
通过 `createBean()` 处理 bean 创建,并通过 `populateBean()` 填充依赖项。包含核心 bean 生命周期逻辑,包括
- 通过 `ConstructorResolver` 进行构造函数解析
- 通过 `AutowiredAnnotationBeanPostProcessor` 进行属性注入
- Bean 初始化回调
AbstractBeanFactory
提供 `doGetBean()` 方法,该方法协调 bean 的检索、创建和缓存。处理父工厂委托和作用域管理。
来源
Bean 定义
Bean 定义是描述如何创建和配置 bean 的元数据对象。`DefaultListableBeanFactory` 将这些定义存储在其 `beanDefinitionMap` 字段中。
BeanDefinition 类层次结构
来源
关键 BeanDefinition 字段
AbstractBeanDefinition 核心字段
`AbstractBeanDefinition` 类包含重要的元数据
| 字段 | 类型 | 目的 |
|---|
beanClass | 对象 | bean 类或类名 |
scope | 字符串 | Bean 作用域(单例、原型等) |
autowireMode | int | 自动装配策略常量 |
dependsOn | String[] | 此 bean 依赖的 bean 名称 |
primary | 布尔值 | 主要自动装配候选标志 |
constructorArgumentValues | ConstructorArgumentValues | 构造函数注入元数据 |
propertyValues | MutablePropertyValues | 属性注入元数据 |
RootBeanDefinition 运行时字段
`RootBeanDefinition` 添加运行时特定的缓存
| 字段 | 类型 | 目的 |
|---|
resolvedConstructorOrFactoryMethod | 可执行文件 | 缓存的构造函数/工厂方法 |
constructorArgumentsResolved | 布尔值 | 构造函数参数是否已解析 |
resolvedConstructorArguments | Object[] | 缓存的已解析构造函数参数 |
来源
自动装配模式常量
`AbstractBeanDefinition` 类定义了自动装配常量
来源
Bean 生命周期
bean 生命周期由 `AbstractAutowireCapableBeanFactory.doCreateBean()` 方法协调,该方法负责 bean 实例化、依赖注入和初始化。
Bean 创建流程
来源
关键生命周期方法
Bean 实例化方法
- `AbstractAutowireCapableBeanFactory.createBeanInstance()`:确定实例化策略
- `ConstructorResolver.autowireConstructor()`:基于构造函数的实例化和依赖解析
- `InstantiationStrategy.instantiate()`:实际对象创建
依赖注入方法
- `AbstractAutowireCapableBeanFactory.populateBean()`:协调属性填充
- `AutowiredAnnotationBeanPostProcessor.postProcessProperties()`:处理 `@Autowired` 注解
- `DefaultListableBeanFactory.resolveDependency()`:按类型解析依赖项
初始化方法
- `AbstractAutowireCapableBeanFactory.initializeBean()`:协调初始化回调
- `InitDestroyAnnotationBeanPostProcessor`:处理 `@PostConstruct`/`@PreDestroy` 注解
- `InitializingBean.afterPropertiesSet()`:编程初始化回调
来源
依赖注入机制
Spring 通过专门的类实现依赖注入,这些类处理不同的注入类型。
通过 ConstructorResolver 进行构造函数注入
`ConstructorResolver` 类处理基于构造函数的依赖注入
关键方法
- `autowireConstructor()`:解析构造函数参数并创建 bean 实例
- `createArgumentArray()`:将构造函数参数与可用 bean 匹配
- `resolvePreparedArguments()`:将参数值转换为目标类型
构造函数解析过程
- 查找候选构造函数(所有构造函数或带有 `@Autowired` 标记的构造函数)
- 按参数数量排序构造函数(贪婪构造函数优先)
- 对于每个构造函数,尝试解析所有参数
- 选择类型匹配度最高且转换要求最少的构造函数
来源
通过 AutowiredAnnotationBeanPostProcessor 进行字段和方法注入
`AutowiredAnnotationBeanPostProcessor` 处理 `@Autowired` 字段和方法注入
核心数据结构
- `injectionMetadataCache`:将 bean 名称映射到 `InjectionMetadata` 对象
- `autowiredAnnotationTypes`:触发注入的注解类型集合(`@Autowired`、`@Value`、`@Inject`)
关键方法
- `findAutowiringMetadata()`:扫描类以查找 `@Autowired` 注解
- `postProcessProperties()`:执行实际的字段/方法注入
- `resolveDependency()`:委托给工厂的依赖解析
每个 bean 都有一个包含以下内容的 `InjectionMetadata`
- `AutowiredFieldElement`:表示 `@Autowired` 字段
- `AutowiredMethodElement`:表示 `@Autowired` 方法
来源
DefaultListableBeanFactory 中的依赖解析
`DefaultListableBeanFactory.resolveDependency()` 方法是核心的依赖解析入口点
解析过程
- 检查 `ObjectFactory`/`ObjectProvider` 包装器请求
- 使用 `getBeanNamesForType()` 按类型查找 bean
- 应用 `AutowireCandidateResolver` 过滤
- 处理多个候选者(使用 `@Primary`、`@Priority`、名称匹配)
- 为注入点元数据创建依赖描述符
关键支持方法
- `findAutowireCandidates()`:查找所有匹配类型的 bean
- `determineAutowireCandidate()`:将多个候选者解析为单个选择
- `isAutowireCandidate()`:检查 bean 是否符合注入条件
来源
自动装配过程
自动装配是通过 `AutowiredAnnotationBeanPostProcessor` 和 `DefaultListableBeanFactory` 之间的协作实现的。
来源
依赖解析链
`DefaultListableBeanFactory.resolveDependency()` 方法协调依赖解析
来源
DependencyDescriptor 和注入点
`DependencyDescriptor` 类表示一个注入点
关键字段
- `declaringClass`:声明注入点的类
- `methodName`/`fieldName`:正在注入的方法或字段的名称
- `required`:依赖是否强制(`@Autowired(required=true)`)
- `eager`:是否急切地解析依赖项
- `nestingLevel`:用于嵌套泛型类型(例如,`List>`)
在解析中的用法
- `MethodParameter` 或 `Field` 被封装在 `DependencyDescriptor` 中
- 描述符被传递给 `DefaultListableBeanFactory.resolveDependency()`
- 解析结果通过反射注入
来源
依赖注入注解
Spring 的依赖注入注解由专门的 `BeanPostProcessor` 实现类处理。
支持的注入注解
`AutowiredAnnotationBeanPostProcessor` 默认识别这些注解类型
| 标注 | 目的 | 处理器 |
|---|
@Autowired | Spring 的自动装配注解 | AutowiredAnnotationBeanPostProcessor |
@Value | 属性/SpEL 表达式注入 | AutowiredAnnotationBeanPostProcessor |
@Inject | JSR-330 标准注入 | AutowiredAnnotationBeanPostProcessor |
该处理器将其存储在其 `autowiredAnnotationTypes` 字段中,并使用 `findAutowiredAnnotation()` 在字段和方法上检测它们。
来源
@Autowired 实现细节
强制依赖与可选依赖
`@Autowired` 注解的 `required` 属性控制异常处理
- `required=true`(默认):如果未找到候选者,则抛出 `UnsatisfiedDependencyException`
- `required=false`:如果未找到候选者,则注入 `null`
这在 `AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement.inject()` 方法中实现。
确定逻辑
`determineRequiredStatus()` 方法使用反射检查注解的 `required` 属性
来源
@Qualifier 处理
限定符解析由 `QualifierAnnotationAutowireCandidateResolver` 处理
关键方法
- `isAutowireCandidate()`:检查 bean 是否符合限定符要求
- `checkQualifiers()`:比较注入点限定符与 bean 定义限定符
- `getQualifiers()`:从 `BeanDefinition` 中提取限定符元数据
限定符匹配过程
- 从注入点提取限定符(`@Qualifier`、自定义限定符注解)
- 从 bean 定义中提取限定符(通过 `AutowireCandidateQualifier` 对象)
- 匹配限定符值和属性
来源
@Primary 和 @Priority 处理
主要 bean 选择在 `DefaultListableBeanFactory.determineAutowireCandidate()` 中实现
选择优先级
- `@Primary` bean 优先于非主要 bean
- `@Priority` 注解值(数字越小优先级越高)
- Bean 名称与注入点名称匹配
- 如果仍然存在歧义,则抛出 `NoUniqueBeanDefinitionException`
该逻辑检查 `BeanDefinition` 中的 `primary` 字段,并使用 `AnnotationAwareOrderComparator` 进行优先级排序。
来源
特殊功能
循环依赖解析
Spring 通过在 `DefaultSingletonBeanRegistry` 中提前暴露 bean 来解决循环依赖
三级缓存系统
- `singletonObjects`:完全初始化的单例 bean
- `earlySingletonObjects`:早期单例对象(未完全初始化)
- `singletonFactories`:用于创建早期单例引用的工厂
解析过程
- Bean A 开始创建,并添加到 `singletonsCurrentlyInCreation`
- Bean A 通过 `addSingletonFactory()` 暴露早期引用
- Bean A 在属性填充期间请求 Bean B
- Bean B 开始创建,并请求 Bean A
- Spring 从 `getSingleton()` 返回 Bean A 的早期引用
- Bean B 使用早期 Bean A 引用完成初始化
- Bean A 使用完全初始化的 Bean B 完成初始化
局限性
- 仅适用于单例作用域
- 至少一个依赖必须是非构造函数注入(setter/字段注入)
- 仅构造函数的循环依赖会抛出 `BeanCurrentlyInCreationException`
来源
用于编程访问依赖项的 ObjectProvider
`ObjectProvider` 接口提供了对依赖项的编程访问,并具有附加功能
ObjectProvider 方法
- `getObject()`:获取单个必需实例(如果未找到则抛出异常)
- `getIfAvailable()`:获取实例,如果不可用则返回 null
- `getIfUnique()`:仅当存在唯一实例时才获取实例
- `stream()`:流式传输所有匹配的 bean
- `orderedStream()`:按序流式传输
在 DefaultListableBeanFactory 中的实现
该工厂在 `getBeanProvider()` 中创建匿名 `ObjectProvider` 实现
来源
Bean 后处理器
Bean 后处理器扩展了 bean 生命周期,以提供依赖注入和其他横切关注点。
BeanPostProcessor 接口层次结构
来源
AutowiredAnnotationBeanPostProcessor 实现
该处理器负责 `@Autowired`、`@Value` 和 `@Inject` 注解的处理
关键数据结构
- `autowiredAnnotationTypes`:包含 `Autowired.class`、`Value.class`、`Inject.class` 的集合
- `injectionMetadataCache`:将 bean 名称映射到缓存的 `InjectionMetadata`
- `candidateConstructorsCache`:缓存类的构造函数候选者
处理阶段
1. 构造函数发现(`determineCandidateConstructors`)
- 扫描类以查找 `@Autowired` 构造函数
- 为 `ConstructorResolver` 返回候选构造函数
- 处理强制与可选构造函数自动装配
2. 元数据缓存(`postProcessMergedBeanDefinition`)
- 调用 `findAutowiringMetadata()` 扫描注入点
- 构建包含 `AutowiredFieldElement` 和 `AutowiredMethodElement` 的 `InjectionMetadata`
- 在 `injectionMetadataCache` 中缓存元数据
3. 依赖注入(`postProcessProperties`)
- 检索缓存的 `InjectionMetadata`
- 调用
InjectionMetadata.inject() 执行实际注入
- 每个元素都会调用
DefaultListableBeanFactory.resolveDependency()
来源
InjectionMetadata 类包含注入元素的集合
元素类型
AutowiredFieldElement:处理 @Autowired 字段注入
AutowiredMethodElement:处理 @Autowired 方法注入
元素注入过程
- 为注入点创建
DependencyDescriptor
- 调用
beanFactory.resolveDependency() 获取依赖
- 使用反射注入已解析的值(
Field.set() 或 Method.invoke())
来源
ApplicationContext 集成
尽管 DefaultListableBeanFactory 提供了核心的 IoC 功能,但 ApplicationContext 实现为企业应用增加了更高级的功能。
基于 BeanFactory 构建的 ApplicationContext
ApplicationContext 实现通常包含一个 DefaultListableBeanFactory 实例
关键的 ApplicationContext 类
AbstractApplicationContext:提供通用功能的基类
GenericApplicationContext:封装了 DefaultListableBeanFactory
AnnotationConfigApplicationContext:增加了基于注解的配置
ClassPathXmlApplicationContext:增加了 XML 配置支持
除了 BeanFactory 之外的额外功能
- 通过
MessageSource 进行消息国际化
- 通过
ApplicationEventPublisher 发布事件
- 通过
ResourceLoader 加载资源
- 针对配置文件和属性的环境抽象
- 自动注册
BeanPostProcessor 和 BeanFactoryPostProcessor bean
来源
配置处理
ApplicationContext 实现会自动处理配置类
ConfigurationClassPostProcessor
- 处理
@Configuration 类
- 处理
@Bean 方法注册
- 处理
@ComponentScan 指令
- 管理
@Import 语句
该处理器创建 BeanDefinition 对象,并将其注册到底层的 DefaultListableBeanFactory 中。
来源
总结
Spring 的 IoC 容器提供了一个精密的依赖注入系统
- 核心架构:
DefaultListableBeanFactory 作为中央 bean 注册表,扩展自 AbstractAutowireCapableBeanFactory 以提供 bean 创建能力
- Bean 定义:
BeanDefinition 对象(通常是 RootBeanDefinition)存储用于 bean 创建的元数据
- 依赖解析:
AutowiredAnnotationBeanPostProcessor 处理注入注解并委托给 DefaultListableBeanFactory.resolveDependency()
- 构造器解析:
ConstructorResolver 处理基于构造器的依赖注入,并具有精密的参数匹配功能
- 生命周期管理:
AbstractAutowireCapableBeanFactory.doCreateBean() 协调完整的 bean 生命周期
- ApplicationContext:在核心
BeanFactory 基础设施之上提供了企业级功能
该系统的强大之处在于其模块化设计,每个组件都具有特定的职责,同时相互协作以提供全面的依赖注入功能。
总结
Spring 的依赖注入容器提供了管理 bean 及其依赖的强大方式
- Bean 定义:Spring 使用
BeanDefinition 对象来保存 bean 的元数据
- Bean 容器:
DefaultListableBeanFactory 是维护 bean 定义的中心注册表
- 依赖注入:Spring 使用构造器、setter 方法和字段来注入依赖
- 自动装配:Spring 使用类型匹配和限定符自动解析和注入依赖
- 后处理器:像
AutowiredAnnotationBeanPostProcessor 这样的 Bean 后处理器增强了 bean 的生命周期
- 注解:像
@Autowired、@Qualifier 和 @Primary 这样的注解控制着注入过程
这种基础设施实现了组件之间的松耦合,使您的代码更易于测试、维护和灵活。