菜单

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 作用域(单例、原型等)
autowireModeint自动装配策略常量
dependsOnString[]此 bean 依赖的 bean 名称
primary布尔值主要自动装配候选标志
constructorArgumentValuesConstructorArgumentValues构造函数注入元数据
propertyValuesMutablePropertyValues属性注入元数据

RootBeanDefinition 运行时字段

`RootBeanDefinition` 添加运行时特定的缓存

字段类型目的
resolvedConstructorOrFactoryMethod可执行文件缓存的构造函数/工厂方法
constructorArgumentsResolved布尔值构造函数参数是否已解析
resolvedConstructorArgumentsObject[]缓存的已解析构造函数参数

来源

自动装配模式常量

`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()`:将参数值转换为目标类型

构造函数解析过程

  1. 查找候选构造函数(所有构造函数或带有 `@Autowired` 标记的构造函数)
  2. 按参数数量排序构造函数(贪婪构造函数优先)
  3. 对于每个构造函数,尝试解析所有参数
  4. 选择类型匹配度最高且转换要求最少的构造函数

来源

通过 AutowiredAnnotationBeanPostProcessor 进行字段和方法注入

`AutowiredAnnotationBeanPostProcessor` 处理 `@Autowired` 字段和方法注入

核心数据结构

  • `injectionMetadataCache`:将 bean 名称映射到 `InjectionMetadata` 对象
  • `autowiredAnnotationTypes`:触发注入的注解类型集合(`@Autowired`、`@Value`、`@Inject`)

关键方法

  • `findAutowiringMetadata()`:扫描类以查找 `@Autowired` 注解
  • `postProcessProperties()`:执行实际的字段/方法注入
  • `resolveDependency()`:委托给工厂的依赖解析

InjectionMetadata 结构

每个 bean 都有一个包含以下内容的 `InjectionMetadata`

  • `AutowiredFieldElement`:表示 `@Autowired` 字段
  • `AutowiredMethodElement`:表示 `@Autowired` 方法

来源

DefaultListableBeanFactory 中的依赖解析

`DefaultListableBeanFactory.resolveDependency()` 方法是核心的依赖解析入口点

解析过程

  1. 检查 `ObjectFactory`/`ObjectProvider` 包装器请求
  2. 使用 `getBeanNamesForType()` 按类型查找 bean
  3. 应用 `AutowireCandidateResolver` 过滤
  4. 处理多个候选者(使用 `@Primary`、`@Priority`、名称匹配)
  5. 为注入点元数据创建依赖描述符

关键支持方法

  • `findAutowireCandidates()`:查找所有匹配类型的 bean
  • `determineAutowireCandidate()`:将多个候选者解析为单个选择
  • `isAutowireCandidate()`:检查 bean 是否符合注入条件

来源

自动装配过程

自动装配是通过 `AutowiredAnnotationBeanPostProcessor` 和 `DefaultListableBeanFactory` 之间的协作实现的。

自动装配元数据发现与注入

来源

依赖解析链

`DefaultListableBeanFactory.resolveDependency()` 方法协调依赖解析

来源

DependencyDescriptor 和注入点

`DependencyDescriptor` 类表示一个注入点

关键字段

  • `declaringClass`:声明注入点的类
  • `methodName`/`fieldName`:正在注入的方法或字段的名称
  • `required`:依赖是否强制(`@Autowired(required=true)`)
  • `eager`:是否急切地解析依赖项
  • `nestingLevel`:用于嵌套泛型类型(例如,`List>`)

在解析中的用法

  1. `MethodParameter` 或 `Field` 被封装在 `DependencyDescriptor` 中
  2. 描述符被传递给 `DefaultListableBeanFactory.resolveDependency()`
  3. 解析结果通过反射注入

来源

依赖注入注解

Spring 的依赖注入注解由专门的 `BeanPostProcessor` 实现类处理。

支持的注入注解

`AutowiredAnnotationBeanPostProcessor` 默认识别这些注解类型

标注目的处理器
@AutowiredSpring 的自动装配注解AutowiredAnnotationBeanPostProcessor
@Value属性/SpEL 表达式注入AutowiredAnnotationBeanPostProcessor
@InjectJSR-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` 中提取限定符元数据

限定符匹配过程

  1. 从注入点提取限定符(`@Qualifier`、自定义限定符注解)
  2. 从 bean 定义中提取限定符(通过 `AutowireCandidateQualifier` 对象)
  3. 匹配限定符值和属性

来源

@Primary 和 @Priority 处理

主要 bean 选择在 `DefaultListableBeanFactory.determineAutowireCandidate()` 中实现

选择优先级

  1. `@Primary` bean 优先于非主要 bean
  2. `@Priority` 注解值(数字越小优先级越高)
  3. Bean 名称与注入点名称匹配
  4. 如果仍然存在歧义,则抛出 `NoUniqueBeanDefinitionException`

该逻辑检查 `BeanDefinition` 中的 `primary` 字段,并使用 `AnnotationAwareOrderComparator` 进行优先级排序。

来源

特殊功能

循环依赖解析

Spring 通过在 `DefaultSingletonBeanRegistry` 中提前暴露 bean 来解决循环依赖

三级缓存系统

  • `singletonObjects`:完全初始化的单例 bean
  • `earlySingletonObjects`:早期单例对象(未完全初始化)
  • `singletonFactories`:用于创建早期单例引用的工厂

解析过程

  1. Bean A 开始创建,并添加到 `singletonsCurrentlyInCreation`
  2. Bean A 通过 `addSingletonFactory()` 暴露早期引用
  3. Bean A 在属性填充期间请求 Bean B
  4. Bean B 开始创建,并请求 Bean A
  5. Spring 从 `getSingleton()` 返回 Bean A 的早期引用
  6. Bean B 使用早期 Bean A 引用完成初始化
  7. 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 和元素结构

InjectionMetadata 类包含注入元素的集合

元素类型

  • AutowiredFieldElement:处理 @Autowired 字段注入
  • AutowiredMethodElement:处理 @Autowired 方法注入

元素注入过程

  1. 为注入点创建 DependencyDescriptor
  2. 调用 beanFactory.resolveDependency() 获取依赖
  3. 使用反射注入已解析的值(Field.set()Method.invoke()

来源

ApplicationContext 集成

尽管 DefaultListableBeanFactory 提供了核心的 IoC 功能,但 ApplicationContext 实现为企业应用增加了更高级的功能。

基于 BeanFactory 构建的 ApplicationContext

ApplicationContext 实现通常包含一个 DefaultListableBeanFactory 实例

关键的 ApplicationContext 类

  • AbstractApplicationContext:提供通用功能的基类
  • GenericApplicationContext:封装了 DefaultListableBeanFactory
  • AnnotationConfigApplicationContext:增加了基于注解的配置
  • ClassPathXmlApplicationContext:增加了 XML 配置支持

除了 BeanFactory 之外的额外功能

  • 通过 MessageSource 进行消息国际化
  • 通过 ApplicationEventPublisher 发布事件
  • 通过 ResourceLoader 加载资源
  • 针对配置文件和属性的环境抽象
  • 自动注册 BeanPostProcessorBeanFactoryPostProcessor bean

来源

配置处理

ApplicationContext 实现会自动处理配置类

ConfigurationClassPostProcessor

  • 处理 @Configuration
  • 处理 @Bean 方法注册
  • 处理 @ComponentScan 指令
  • 管理 @Import 语句

该处理器创建 BeanDefinition 对象,并将其注册到底层的 DefaultListableBeanFactory 中。

来源

总结

Spring 的 IoC 容器提供了一个精密的依赖注入系统

  1. 核心架构DefaultListableBeanFactory 作为中央 bean 注册表,扩展自 AbstractAutowireCapableBeanFactory 以提供 bean 创建能力
  2. Bean 定义BeanDefinition 对象(通常是 RootBeanDefinition)存储用于 bean 创建的元数据
  3. 依赖解析AutowiredAnnotationBeanPostProcessor 处理注入注解并委托给 DefaultListableBeanFactory.resolveDependency()
  4. 构造器解析ConstructorResolver 处理基于构造器的依赖注入,并具有精密的参数匹配功能
  5. 生命周期管理AbstractAutowireCapableBeanFactory.doCreateBean() 协调完整的 bean 生命周期
  6. ApplicationContext:在核心 BeanFactory 基础设施之上提供了企业级功能

该系统的强大之处在于其模块化设计,每个组件都具有特定的职责,同时相互协作以提供全面的依赖注入功能。

总结

Spring 的依赖注入容器提供了管理 bean 及其依赖的强大方式

  1. Bean 定义:Spring 使用 BeanDefinition 对象来保存 bean 的元数据
  2. Bean 容器DefaultListableBeanFactory 是维护 bean 定义的中心注册表
  3. 依赖注入:Spring 使用构造器、setter 方法和字段来注入依赖
  4. 自动装配:Spring 使用类型匹配和限定符自动解析和注入依赖
  5. 后处理器:像 AutowiredAnnotationBeanPostProcessor 这样的 Bean 后处理器增强了 bean 的生命周期
  6. 注解:像 @Autowired@Qualifier@Primary 这样的注解控制着注入过程

这种基础设施实现了组件之间的松耦合,使您的代码更易于测试、维护和灵活。