0源码基础学习Spring源码系列(一)——Bean注入流程
字数 2520 2025-08-11 17:40:22

Spring源码学习:Bean注入流程详解

一、@Autowired与@Resource的区别

核心区别

  • @Autowired:先通过类型注入(byType),当存在多个类型时再通过名称注入(byName)
  • @Resource:先通过名称注入(byName),当名称不存在或有多个名称时再通过类型注入

注入示例分析

// 接口定义
interface StuService {
    String getName();
}

// 实现类1
@Service
class Stu2 implements StuService {
    @Override public String getName() { return "stu2"; }
}

// 实现类2
@Service
class Stu3 implements StuService {
    @Override public String getName() { return "stu3"; }
}

@Autowired使用场景

  1. 单一类型直接注入:
@Autowired
SessionUtil sessionUtil; // 只有一个实现类,直接注入
  1. 多实现类需指定名称:
@Autowired
StuService stu; // 报错,需要指定stu2或stu3
@Autowired
StuService stu2; // 正确注入

@Resource使用场景

  1. 通过名称注入:
@Resource(name = "stu2")
private StuService stu1;
  1. 类型不匹配问题:
@Resource
private Stu3 stu2; // 报错,期望Stu3但找到Stu2

Bean命名规则

  1. 默认命名:类名首字母小写
  2. 自定义命名:
@Service("stu2") // 自定义bean名称为stu2
@Bean("stu1")    // 自定义bean名称为stu1

二、Spring IOC核心概念

1. 配置元数据

描述bean的配置信息,可以是:

  • XML文件
  • Properties/YAML文件
  • 注解(@Service, @Component等)

2. BeanDefinition

  • 内存中描述bean的元数据对象
  • 相当于bean的生成模板或说明书
  • 由BeanDefinitionReader从配置元数据转换而来

3. BeanDefinitionReader

负责将不同格式的配置元数据转换为BeanDefinition:

  • XmlBeanDefinitionReader:读取XML配置
  • PropertiesBeanDefinitionReader:读取properties配置
  • AnnotatedBeanDefinitionReader:读取注解配置

4. BeanFactoryPostProcessor

容器启动阶段的扩展点,用于修改BeanDefinition:

  • 修改已注册的BeanDefinition
  • 典型应用:属性占位符替换
<property name="url" value="${jdbc.url}"/>

5. BeanDefinitionRegistry

存储BeanDefinition的注册中心,采用KV结构:

  • Key: beanName
  • Value: BeanDefinition

6. BeanFactory vs FactoryBean

  • BeanFactory:bean的工厂,负责创建和管理bean
  • FactoryBean:特殊的bean,可以生产其他bean

FactoryBean示例

@Component
class FactoryBeanDemo implements FactoryBean<Student> {
    @Override public Student getObject() { return new Student(); }
    @Override public Class<?> getObjectType() { return Student.class; }
}
  • 获取FactoryBean生产的bean:@Resource private Object factoryBeanDemo
  • 获取FactoryBean本身:@Resource(name = "&factoryBeanDemo")

三、Bean注入流程详解

1. 容器启动阶段

  1. 读取配置元数据
  2. 转换为BeanDefinition
  3. 注册到BeanDefinitionRegistry
  4. 执行BeanFactoryPostProcessor修改BeanDefinition

2. Bean实例化阶段

核心方法:doGetBean()

主要流程:

  1. 尝试从缓存获取bean
  2. 未命中则创建bean
  3. 处理依赖的bean
  4. 根据scope创建bean实例
  5. 属性填充
  6. 初始化

3. 详细创建流程:doCreateBean

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args) {
    // 1. 实例化bean
    BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);
    
    // 2. 解析注解(@Autowired, @Resource等)
    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
    
    // 3. 提前曝光解决循环依赖
    addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    
    // 4. 属性填充
    populateBean(beanName, mbd, instanceWrapper);
    
    // 5. 初始化
    exposedObject = initializeBean(beanName, exposedObject, mbd);
    
    // 6. 循环依赖检查
    if (earlySingletonExposure) {...}
    
    // 7. 注册bean
    registerDisposableBeanIfNecessary(beanName, bean, mbd);
    
    return exposedObject;
}

4. 关键步骤详解

4.1 createBeanInstance:实例化bean

  1. 解析bean class并验证访问权限
  2. 处理Supplier回调
  3. 处理工厂方法
  4. 自动装配构造函数
  5. 默认使用无参构造函数

构造函数解析逻辑

  1. 查找@Autowired注解的构造方法
  2. 只有一个有参构造方法时直接使用
  3. 无特殊标记时使用无参构造方法

最终通过反射创建实例:

ctor.newInstance(argsWithDefaultValues);

4.2 populateBean:属性注入

  1. 遍历InstantiationAwareBeanPostProcessor
  2. 处理@Autowired/@Value注解(AutowiredAnnotationBeanPostProcessor)
  3. 处理@Resource注解(CommonAnnotationBeanPostProcessor)

注入实现

// 字段注入
field.set(target, getResourceToInject(target, requestingBeanName));
// 方法注入
method.invoke(target, getResourceToInject(target, requestingBeanName));

依赖解析:

resource = beanFactory.resolveBeanByName(name, descriptor);
// 或
resource = factory.getBean(name, element.lookupType);

4.3 initializeBean:初始化bean

  1. 前置处理(@PostConstruct方法执行)
  2. 调用初始化方法(InitializingBean.afterPropertiesSet和init-method)
  3. 后置处理(AOP代理在此发生)

初始化顺序

  1. @PostConstruct注解方法
  2. InitializingBean.afterPropertiesSet()
  3. init-method指定方法

5. BeanPostProcessor vs BeanFactoryPostProcessor

特性 BeanFactoryPostProcessor BeanPostProcessor
执行阶段 容器启动阶段 对象实例化阶段
关注点 Bean创建前的配置修改 Bean创建后的功能增强/替换
典型应用 属性占位符替换 AOP代理、@PostConstruct处理

四、总结

Spring Bean注入的核心流程可归纳为:

  1. 配置解析:将各种配置元数据转换为BeanDefinition
  2. 实例化:通过反射创建bean实例
  3. 属性填充:解析并注入依赖属性
  4. 初始化:执行初始化方法和AOP代理

关键扩展点:

  • BeanFactoryPostProcessor:修改BeanDefinition
  • BeanPostProcessor:增强bean功能
  • FactoryBean:特殊bean的生产工厂

理解这些核心概念和流程,是深入掌握Spring IoC容器的基础。

Spring源码学习:Bean注入流程详解 一、@Autowired与@Resource的区别 核心区别 @Autowired :先通过类型注入(byType),当存在多个类型时再通过名称注入(byName) @Resource :先通过名称注入(byName),当名称不存在或有多个名称时再通过类型注入 注入示例分析 @Autowired使用场景 单一类型直接注入: 多实现类需指定名称: @Resource使用场景 通过名称注入: 类型不匹配问题: Bean命名规则 默认命名:类名首字母小写 自定义命名: 二、Spring IOC核心概念 1. 配置元数据 描述bean的配置信息,可以是: XML文件 Properties/YAML文件 注解(@Service, @Component等) 2. BeanDefinition 内存中描述bean的元数据对象 相当于bean的生成模板或说明书 由BeanDefinitionReader从配置元数据转换而来 3. BeanDefinitionReader 负责将不同格式的配置元数据转换为BeanDefinition: XmlBeanDefinitionReader:读取XML配置 PropertiesBeanDefinitionReader:读取properties配置 AnnotatedBeanDefinitionReader:读取注解配置 4. BeanFactoryPostProcessor 容器启动阶段的扩展点,用于修改BeanDefinition: 修改已注册的BeanDefinition 典型应用:属性占位符替换 5. BeanDefinitionRegistry 存储BeanDefinition的注册中心,采用KV结构: Key: beanName Value: BeanDefinition 6. BeanFactory vs FactoryBean BeanFactory :bean的工厂,负责创建和管理bean FactoryBean :特殊的bean,可以生产其他bean FactoryBean示例 获取FactoryBean生产的bean: @Resource private Object factoryBeanDemo 获取FactoryBean本身: @Resource(name = "&factoryBeanDemo") 三、Bean注入流程详解 1. 容器启动阶段 读取配置元数据 转换为BeanDefinition 注册到BeanDefinitionRegistry 执行BeanFactoryPostProcessor修改BeanDefinition 2. Bean实例化阶段 核心方法: doGetBean() 主要流程: 尝试从缓存获取bean 未命中则创建bean 处理依赖的bean 根据scope创建bean实例 属性填充 初始化 3. 详细创建流程:doCreateBean 4. 关键步骤详解 4.1 createBeanInstance:实例化bean 解析bean class并验证访问权限 处理Supplier回调 处理工厂方法 自动装配构造函数 默认使用无参构造函数 构造函数解析逻辑 : 查找@Autowired注解的构造方法 只有一个有参构造方法时直接使用 无特殊标记时使用无参构造方法 最终通过反射创建实例: 4.2 populateBean:属性注入 遍历InstantiationAwareBeanPostProcessor 处理@Autowired/@Value注解(AutowiredAnnotationBeanPostProcessor) 处理@Resource注解(CommonAnnotationBeanPostProcessor) 注入实现 : 依赖解析: 4.3 initializeBean:初始化bean 前置处理( @PostConstruct 方法执行) 调用初始化方法(InitializingBean.afterPropertiesSet和init-method) 后置处理(AOP代理在此发生) 初始化顺序 : @PostConstruct注解方法 InitializingBean.afterPropertiesSet() init-method指定方法 5. BeanPostProcessor vs BeanFactoryPostProcessor | 特性 | BeanFactoryPostProcessor | BeanPostProcessor | |---------------------|----------------------------------|---------------------------------| | 执行阶段 | 容器启动阶段 | 对象实例化阶段 | | 关注点 | Bean创建前的配置修改 | Bean创建后的功能增强/替换 | | 典型应用 | 属性占位符替换 | AOP代理、@PostConstruct处理 | 四、总结 Spring Bean注入的核心流程可归纳为: 配置解析 :将各种配置元数据转换为BeanDefinition 实例化 :通过反射创建bean实例 属性填充 :解析并注入依赖属性 初始化 :执行初始化方法和AOP代理 关键扩展点: BeanFactoryPostProcessor:修改BeanDefinition BeanPostProcessor:增强bean功能 FactoryBean:特殊bean的生产工厂 理解这些核心概念和流程,是深入掌握Spring IoC容器的基础。