【Spring源码】getBean源码实战(一)

getBean源码实战(一)

代码仓库Gitee 仓库链接

本文档的所有示例代码都可以在代码仓库中找到,建议结合代码一起阅读。

1. 获取一个最简单的 Bean

1.1 示例 Bean:UserService

我们以一个最简单的 UserService 为例,来追踪 getBean() 方法的执行过程。

Bean 类定义

1:25:spring-source/code/spring-basic/src/main/java/com/example/basic/UserService.java 复制代码
package com.example.basic;

/**
 * 简单的UserService类,用于演示bean标签的基本属性
 */
public class UserService {
    
    private String name;
    
    public UserService() {
        System.out.println("UserService 构造函数被调用");
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public void sayHello() {
        System.out.println("Hello, I am UserService");
    }
}

XML 配置

7:9:spring-source/code/spring-basic/src/main/resources/bean-basic-attributes.xml 复制代码
    <!-- 简单的bean标签示例:包含id、name、class属性 -->
    <bean id="userService" name="userServiceAlias,userServiceAlias2" class="com.example.basic.UserService">
    </bean>

获取 Bean 的代码

15:24:spring-source/code/spring-basic/src/test/java/com/example/basic/BeanBasicAttributesTest.java 复制代码
    @Test
    public void testBeanWithIdNameClass() {
        // 加载XML配置文件
        BeanFactory factory = new XmlBeanFactory(
            new ClassPathResource("bean-basic-attributes.xml")
        );
        
        // 通过id获取bean
        UserService userServiceById = (UserService) factory.getBean("userService");
        assertNotNull(userServiceById);

1.2 代码仓库位置

  • Bean 类code/spring-basic/src/main/java/com/example/basic/UserService.java
  • 配置文件code/spring-basic/src/main/resources/bean-basic-attributes.xml
  • 测试类code/spring-basic/src/test/java/com/example/basic/BeanBasicAttributesTest.java

1.3 执行流程概述

当我们调用 factory.getBean("userService") 时,Spring 会执行以下步骤:

  1. 名称转换 :将 "userService" 转换为实际的 Bean 名称(处理别名)
  2. 缓存查找:从单例缓存中查找是否已存在该 Bean 实例
  3. Bean 定义获取:获取合并后的 Bean 定义
  4. 依赖处理:检查并处理该 Bean 的依赖关系
  5. Bean 创建:根据作用域创建 Bean 实例(单例或原型)
  6. 返回实例:返回创建或缓存的 Bean 实例

对于这个最简单的 UserService,它没有依赖、没有属性注入、使用默认的单例作用域,所以执行流程相对简单。接下来我们将深入源码,逐步分析每个步骤的具体实现。

1.4 深入 doGetBean 方法

getBean() 方法最终会调用 AbstractBeanFactory.doGetBean() 方法,这是 Bean 获取的核心方法。让我们逐步分析这个方法对 UserService 的处理过程:

步骤 1:翻译 Bean 名称

源码位置AbstractBeanFactory.doGetBean()

java 复制代码
// AbstractBeanFactory.java
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType,
        @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
    
    // 步骤1:翻译Bean名称
    final String beanName = transformedBeanName(name);
    
    // ... 后续步骤
}

作用:将传入的 Bean 名称转换为实际的 Bean 名称。

  • 对于 "userService",由于它不是别名,也不是 FactoryBean 的特殊前缀,所以转换后仍然是 "userService"
  • 如果传入的是别名(如 "userServiceAlias"),会通过别名映射表转换为实际的 Bean 名称 "userService"
  • 如果传入的是 "&userService"(获取 FactoryBean 本身),会去掉 & 前缀。

transformedBeanName 方法实现

java 复制代码
// AbstractBeanFactory.java
protected String transformedBeanName(String name) {
    return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
  • BeanFactoryUtils.transformedBeanName():处理 FactoryBean 的前缀 &
  • canonicalName():将别名转换为实际的 Bean 名称
步骤 2:获取单例 Bean

源码位置AbstractBeanFactory.doGetBean()

java 复制代码
// AbstractBeanFactory.java
protected <T> T doGetBean(...) {
    final String beanName = transformedBeanName(name);
    
    // 步骤2:尝试从缓存获取单例Bean
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }
    else {
        // 首次获取,缓存中不存在,进入创建流程
        // ... 后续步骤
    }
}

作用:从单例缓存中尝试获取已存在的 Bean 实例。

  • 因为是首次获取,单例缓存中不存在,所以 sharedInstancenull
  • 此时会进入需要初始化 Bean 的逻辑分支。

getSingleton 方法实现

java 复制代码
// DefaultSingletonBeanRegistry.java
public Object getSingleton(String beanName) {
    return getSingleton(beanName, true);
}

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // 第一级缓存:完全初始化好的单例Bean
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        synchronized (this.singletonObjects) {
            // 第二级缓存:提前暴露的单例Bean
            singletonObject = this.earlySingletonObjects.get(beanName);
            if (singletonObject == null && allowEarlyReference) {
                // 第三级缓存:单例Bean的工厂对象
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                if (singletonFactory != null) {
                    singletonObject = singletonFactory.getObject();
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    return singletonObject;
}

缓存结构

  • singletonObjects:一级缓存,存储完全初始化好的单例 Bean
  • earlySingletonObjects:二级缓存,存储提前暴露的单例 Bean(用于解决循环依赖)
  • singletonFactories:三级缓存,存储单例 Bean 的工厂对象
步骤 3:检查循环依赖

说明:对于单例 Bean,Spring 支持循环依赖的解决机制。

  • 由于 UserService 是默认的单例作用域,且没有依赖其他 Bean,所以不需要处理循环依赖。
  • 如果存在循环依赖,会通过三级缓存机制来解决。
步骤 4:检查父级 BeanFactory

源码位置AbstractBeanFactory.doGetBean()

java 复制代码
// AbstractBeanFactory.java
protected <T> T doGetBean(...) {
    // ... 前面的步骤
    
    // 步骤4:检查父级BeanFactory
    BeanFactory parentBeanFactory = getParentBeanFactory();
    if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
        // 由父级BeanFactory处理
        String nameToLookup = originalBeanName(name);
        if (parentBeanFactory instanceof AbstractBeanFactory) {
            return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                    nameToLookup, requiredType, args, typeCheckOnly);
        }
        // ... 其他处理逻辑
    }
    
    // ... 后续步骤
}

作用:如果当前 BeanFactory 中不存在该 Bean 定义,尝试从父级 BeanFactory 获取。

  • 对于我们的示例,没有配置父级 BeanFactory,所以跳过这个逻辑。
步骤 5:标记 Bean 正在创建

源码位置AbstractBeanFactory.doGetBean()

java 复制代码
// AbstractBeanFactory.java
protected <T> T doGetBean(...) {
    // ... 前面的步骤
    
    // 步骤5:标记Bean正在创建
    if (!typeCheckOnly) {
        markBeanAsCreated(beanName);
    }
    
    // ... 后续步骤
}

作用:标记该 Bean 正在被创建,防止重复创建。

markBeanAsCreated 方法实现

java 复制代码
// AbstractBeanFactory.java
protected void markBeanAsCreated(String beanName) {
    if (!this.alreadyCreated.contains(beanName)) {
        synchronized (this.mergedBeanDefinitions) {
            if (!this.alreadyCreated.contains(beanName)) {
                // 双检查:确保线程安全
                this.alreadyCreated.add(beanName);
                // 清理合并后的Bean定义缓存,后续会重新合并
                this.mergedBeanDefinitions.remove(beanName);
            }
        }
    }
}

具体操作

  • 双检查 alreadyCreated 集合中是否已存在该 beanName
  • 如果不存在,则将其加入 alreadyCreated 集合。
  • 同时清理 mergedBeanDefinitions 缓存中的该 beanName,因为后续会重新合并 Bean 定义。

注意typeCheckOnly 参数表示是否仅进行类型检查。如果是 true,则不会标记 Bean 为正在创建状态。

步骤 6:ApplicationStartup 处理

源码位置AbstractBeanFactory.doGetBean()

java 复制代码
// AbstractBeanFactory.java
protected <T> T doGetBean(...) {
    // ... 前面的步骤
    
    // 步骤6:ApplicationStartup处理(性能监控,本次不关注)
    // StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate");
    // 默认的applicationStartup是DefaultApplicationStartup,不做任何实际处理
    // 主要用于性能监控和调试,可以通过自定义ApplicationStartup实现来收集Bean创建的耗时信息
    
    // ... 后续步骤
}

说明StartupStep 的具体用途在源码中主要用于性能追踪,但在默认情况下不会产生实际影响。本次不关注此逻辑。

步骤 7:获取合并后的 Bean 定义

源码位置AbstractBeanFactory.doGetBean()

java 复制代码
// AbstractBeanFactory.java
protected <T> T doGetBean(...) {
    // ... 前面的步骤
    
    // 步骤7:获取合并后的Bean定义
    RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    
    // ... 后续步骤
}

作用 :获取合并后的 Bean 定义(RootBeanDefinition)。

getMergedLocalBeanDefinition 方法实现

java 复制代码
// AbstractBeanFactory.java
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) {
    // 先检查缓存
    RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
    if (mbd != null) {
        return mbd;
    }
    // 从beanDefinitionMap中获取原始Bean定义
    return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}

protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd) {
    return getMergedBeanDefinition(beanName, bd, null);
}

protected RootBeanDefinition getMergedBeanDefinition(
        String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd) {
    
    synchronized (this.mergedBeanDefinitions) {
        RootBeanDefinition mbd;
        
        // 检查缓存
        mbd = this.mergedBeanDefinitions.get(beanName);
        if (mbd != null) {
            return mbd;
        }
        
        // 如果没有父级Bean定义,直接封装成RootBeanDefinition
        if (bd.getParentName() == null) {
            if (bd instanceof RootBeanDefinition) {
                mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
            }
            else {
                mbd = new RootBeanDefinition(bd);
            }
        }
        else {
            // 有父级Bean定义,需要合并(本次不关注)
            // ... 合并逻辑
        }
        
        // 设置默认作用域(如果没有设置scope,默认为singleton)
        if (!StringUtils.hasLength(mbd.getScope())) {
            mbd.setScope(SCOPE_SINGLETON);
        }
        
        // 缓存合并后的Bean定义
        this.mergedBeanDefinitions.put(beanName, mbd);
        return mbd;
    }
}

处理过程

  1. 首先检查 mergedBeanDefinitions 缓存中是否已存在合并后的 Bean 定义。
  2. 如果缓存不存在,从 beanDefinitionMap 中获取原始的 Bean 定义(GenericBeanDefinition)。
  3. 对于 UserService,由于没有父级 Bean 定义,所以不需要合并父级的属性,直接封装成 RootBeanDefinition
  4. 设置默认作用域:由于配置中没有设置 scope 属性,所以默认设置为 singleton(单例)。
  5. 缓存合并后的 Bean 定义,供后续使用。
步骤 8:检查是否为抽象 Bean

源码位置AbstractBeanFactory.doGetBean()

java 复制代码
// AbstractBeanFactory.java
protected <T> T doGetBean(...) {
    // ... 前面的步骤
    
    // 步骤8:检查是否为抽象Bean
    if (mbd.isAbstract()) {
        throw new BeanIsAbstractException(beanName);
    }
    
    // ... 后续步骤
}

作用:检查 Bean 定义是否为抽象 Bean。

  • 如果 Bean 定义标记为 abstract="true",则无法实例化,在此处抛出 BeanIsAbstractException 异常。
  • 对于 UserService,它不是抽象 Bean,所以可以正常通过检查。

设计目的:抽象 Bean 通常用于作为父模板,供其他 Bean 继承使用,本身不应该被实例化。


总结 :通过以上 8 个步骤,doGetBean() 方法完成了 Bean 获取的前期准备工作,包括名称转换、缓存查找、Bean 定义获取和验证等。接下来将进入 Bean 的实际创建过程。

步骤 9:检查 depends-on 依赖

源码位置AbstractBeanFactory.doGetBean()

java 复制代码
// AbstractBeanFactory.java
protected <T> T doGetBean(...) {
    // ... 前面的步骤
    
    // 步骤9:检查depends-on依赖(本次不关注)
    // String[] dependsOn = mbd.getDependsOn();
    // if (dependsOn != null) {
    //     // 处理依赖关系:递归获取依赖的Bean
    //     for (String dep : dependsOn) {
    //         if (isDependent(beanName, dep)) {
    //             throw new BeanCreationException(...); // 循环依赖检查
    //         }
    //         registerDependentBean(dep, beanName);
    //         getBean(dep); // 递归获取依赖的Bean
    //     }
    // }
    
    // ... 后续步骤
}

说明 :由于 UserService 没有配置 depends-on,所以 dependsOnnull,这段代码跳过。

步骤 10:进入单例创建逻辑

源码位置AbstractBeanFactory.doGetBean()

java 复制代码
// AbstractBeanFactory.java
protected <T> T doGetBean(...) {
    // ... 前面的步骤
    
    // 步骤10:进入单例创建逻辑
    if (mbd.isSingleton()) {
        sharedInstance = getSingleton(beanName, () -> {
            return createBean(beanName, mbd, args);
        });
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    }
    // else if (mbd.isPrototype()) { ... } // 原型Bean处理(本次不关注)
    // else { ... } // 其他作用域处理(本次不关注)
}

作用 :由于 UserService 是单例作用域,进入单例 Bean 的创建逻辑。

  • 调用 getSingleton(String beanName, ObjectFactory<?> singletonFactory) 方法。
  • 传入一个 ObjectFactory,用于创建 Bean 实例(延迟执行)。
步骤 11:再次检查单例缓存

源码位置DefaultSingletonBeanRegistry.getSingleton(String, ObjectFactory)

java 复制代码
// DefaultSingletonBeanRegistry.java
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    synchronized (this.singletonObjects) {
        // 再次从一级缓存中获取
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null) {
            // 检查是否正在销毁
            if (this.singletonsCurrentlyInDestruction.contains(beanName)) {
                throw new BeanCreationNotAllowedException(beanName,
                        "Singleton bean creation not allowed while singletons of this factory are in destruction");
            }
            
            // 打印创建开始的日志
            if (logger.isDebugEnabled()) {
                logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
            }
            
            // ... 后续步骤
        }
        return singletonObject;
    }
}

作用:在同步块中再次从一级缓存中获取单例 Bean。

处理过程

  1. 如果获取不到,进入创建流程。
  2. 检查是否正在销毁 :检查该 Bean 是否在 singletonsCurrentlyInDestruction 集合中,如果存在则抛出 BeanCreationNotAllowedException 异常(防止在销毁过程中创建 Bean)。
  3. 打印创建开始的日志:记录 Bean 开始创建的信息。
步骤 12:标记 Bean 正在创建

源码位置DefaultSingletonBeanRegistry.getSingleton(String, ObjectFactory)

java 复制代码
// DefaultSingletonBeanRegistry.java
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    synchronized (this.singletonObjects) {
        // ... 前面的步骤
        
        // 步骤12:标记Bean正在创建
        beforeSingletonCreation(beanName);
        
        // ... 后续步骤
    }
}

protected void beforeSingletonCreation(String beanName) {
    // 检查inCreationCheckExclusions是否包含该beanName
    // 如果不包含,才进行后续检查(具体用途需要进一步研究)
    if (!this.inCreationCheckExclusions.contains(beanName) &&
            !this.singletonsCurrentlyInCreation.add(beanName)) {
        // 如果已存在,说明存在循环依赖或重复创建,抛出异常
        throw new BeanCurrentlyInCreationException(beanName);
    }
}

作用 :将 beanName 放入 singletonsCurrentlyInCreation 集合,标记该 Bean 正在创建中。

处理过程

  1. 检查 inCreationCheckExclusions 集合是否包含该 beanName(如果不包含,才进行后续检查)。
    • 说明inCreationCheckExclusions 用于排除某些 Bean 的创建检查,具体用途需要进一步研究。
  2. 如果 singletonsCurrentlyInCreation 中已存在该 beanName,说明存在循环依赖或重复创建,抛出异常。
  3. beanName 添加到 singletonsCurrentlyInCreation 集合中。
步骤 13:初始化异常集合

源码位置DefaultSingletonBeanRegistry.getSingleton(String, ObjectFactory)

java 复制代码
// DefaultSingletonBeanRegistry.java
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    synchronized (this.singletonObjects) {
        // ... 前面的步骤
        
        // 步骤13:初始化异常集合(本次不关注具体用途)
        this.suppressedExceptions = new LinkedHashSet<>();
        
        // ... 后续步骤
    }
}

说明:初始化一个异常集合,用于收集在 Bean 创建过程中被抑制的异常。这个集合用于在 Bean 创建失败时,收集所有相关的异常信息,便于问题排查。具体使用场景需要进一步研究。

步骤 14:进入 createBean 方法

源码位置AbstractAutowireCapableBeanFactory.createBean()

java 复制代码
// AbstractAutowireCapableBeanFactory.java
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // 步骤14:由于mbd参数可能在后续处理中被修改,为了避免改变入参指向的对象地址,
    // 新声明一个RootBeanDefinition并指向入参的Bean定义对象
    RootBeanDefinition mbdToUse = mbd;
    
    // ... 后续步骤
}

作用 :进入 AbstractAutowireCapableBeanFactory.createBean() 方法,开始 Bean 的创建过程。

关键操作

  • 由于 mbd 参数可能在后续处理中被修改,为了避免改变入参指向的对象地址,新声明一个 RootBeanDefinition mbdToUse 并指向入参的 Bean 定义对象。
  • 这样可以确保原始 Bean 定义不被修改,同时可以使用修改后的 Bean 定义进行后续处理。
步骤 15:解析 Bean 的 Class 类型

源码位置AbstractAutowireCapableBeanFactory.createBean()

java 复制代码
// AbstractAutowireCapableBeanFactory.java
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    RootBeanDefinition mbdToUse = mbd;
    
    // 步骤15:解析Bean的Class类型
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }
    
    // ... 后续步骤
}

resolveBeanClass 方法实现

java 复制代码
// AbstractBeanFactory.java
protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch) {
    try {
        if (mbd.hasBeanClass()) {
            return mbd.getBeanClass();
        }
        return doResolveBeanClass(mbd, typesToMatch);
    }
    catch (ClassNotFoundException ex) {
        // ... 异常处理
    }
}

private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch) {
    // 进行一系列判断和检查(具体逻辑需要进一步研究)
    // 最终调用mbd.resolveBeanClass(beanClassLoader)方法,通过类加载器加载Class对象
    return mbd.resolveBeanClass(getBeanClassLoader());
}

作用:根据 Bean 定义、Bean 名称和参数解析 Bean 的 Class 类型。

处理过程

  1. 对于 UserService 这种简单的 Bean,理论上应该能够直接从 Bean 定义中获取类型。
  2. 但实际上,Bean 定义中只存储了全限定类名(字符串),需要通过类加载器加载 Class 对象。
  3. 调用 doResolveBeanClass() 方法:
    • 进行一系列判断和检查(具体逻辑需要进一步研究)。
    • 最终调用 mbd.resolveBeanClass(beanClassLoader) 方法,通过类加载器加载 Class 对象。
  4. 将解析得到的 Class 对象设置到 Bean 定义中,供后续使用。

注意:Bean 定义加载时只存储了类名的字符串,实际的 Class 对象是在创建 Bean 时才加载的,这是延迟加载的体现。

步骤 16:准备方法覆盖

源码位置AbstractAutowireCapableBeanFactory.createBean()

java 复制代码
// AbstractAutowireCapableBeanFactory.java
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // ... 前面的步骤
    
    // 步骤16:准备方法覆盖(本次不关注)
    // mbdToUse.prepareMethodOverrides();
    // 由于UserService没有配置任何方法覆盖逻辑(lookup-method和replaced-method),所以跳过
    
    // ... 后续步骤
}

说明 :由于 UserService 没有配置任何方法覆盖逻辑,所以这个方法跳过,不做任何处理。

步骤 17:实例化前的后置处理

源码位置AbstractAutowireCapableBeanFactory.createBean()

java 复制代码
// AbstractAutowireCapableBeanFactory.java
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // ... 前面的步骤
    
    // 步骤17:实例化前的后置处理(本次不关注)
    // Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    // if (bean != null) {
    //     return bean; // 如果返回了非null的对象,则直接返回,不再进行后续的实例化过程
    // }
    // 对于UserService,没有配置任何InstantiationAwareBeanPostProcessor,所以这段逻辑没有走进去
    
    // ... 后续步骤
}

说明 :在 Bean 实例化之前,给 BeanPostProcessor 一个机会返回代理对象。对于 UserService,没有配置任何 InstantiationAwareBeanPostProcessor,所以这段逻辑没有走进去。

步骤 18:进入 doCreateBean 方法

源码位置AbstractAutowireCapableBeanFactory.createBean()

java 复制代码
// AbstractAutowireCapableBeanFactory.java
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // ... 前面的步骤
    
    // 步骤18:进入doCreateBean方法,执行实际的Bean创建逻辑
    Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    return beanInstance;
}

doCreateBean 方法开始

java 复制代码
// AbstractAutowireCapableBeanFactory.java
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // 从factoryBeanInstanceCache缓存中清理掉该beanName(如果存在)
    // 对于UserService这种简单的Bean,没有这个逻辑,需要重新创建
    
    // ... 后续步骤
}

作用 :进入 doCreateBean() 方法,执行实际的 Bean 创建逻辑。

步骤 19:创建 Bean 实例

源码位置AbstractAutowireCapableBeanFactory.doCreateBean()

java 复制代码
// AbstractAutowireCapableBeanFactory.java
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // 步骤19:创建Bean实例
    BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);
    Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    
    // ... 后续步骤
}

createBeanInstance 方法实现

java 复制代码
// AbstractAutowireCapableBeanFactory.java
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // 1. 检查构造方法可见性
    // 如果Bean定义中的类型没有对外暴露构造方法(所有构造方法都是私有的),则抛出异常
    
    // 2. 获取实例提供者(本次不关注)
    // Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    // if (instanceSupplier != null) { ... }
    
    // 3. 检查工厂方法(本次不关注)
    // String factoryBeanName = mbd.getFactoryBeanName();
    // if (factoryBeanName != null) { ... }
    
    // 4. 确定构造方法
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    // 返回null(没有配置相关的后置处理器)
    
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
            mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
        // 有构造参数的情况(本次不关注)
        // return autowireConstructor(beanName, mbd, ctors, args);
    }
    
    // 5. 使用默认构造方法
    ctors = mbd.getPreferredConstructors();
    // 返回null(没有配置)
    
    // 最终走instantiateBean方法,使用默认的无参构造方法创建实例
    return instantiateBean(beanName, mbd);
}

作用:根据 Bean 定义创建 Bean 实例。

处理过程

  1. 检查构造方法可见性:如果 Bean 定义中的类型没有对外暴露构造方法,则抛出异常。
  2. 获取实例提供者:调用 getInstanceSupplier(),如果为空则继续后续逻辑。
  3. 检查工厂方法:如果没有 factoryMethodName,则走基础逻辑。
  4. 确定构造方法:
    • 调用 determineConstructorsFromBeanPostProcessors() 方法,返回 null(没有配置相关的后置处理器)。
    • 调用 mbd.getPreferredConstructors() 获取首选的构造方法,返回 null(没有配置)。
  5. 使用默认构造方法:最终走 instantiateBean(beanName, mbd) 方法,使用默认的无参构造方法创建实例。
步骤 20:使用 SimpleInstantiationStrategy 创建实例

源码位置AbstractAutowireCapableBeanFactory.instantiateBean()

java 复制代码
// AbstractAutowireCapableBeanFactory.java
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
    try {
        Object beanInstance;
        // 使用SimpleInstantiationStrategy创建实例
        if (mbd.getResolvedTargetType() != null) {
            beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
        }
        else {
            // ... 其他情况(本次不关注)
        }
        BeanWrapper bw = new BeanWrapperImpl(beanInstance);
        initBeanWrapper(bw);
        return bw;
    }
    catch (Throwable ex) {
        // ... 异常处理
    }
}

SimpleInstantiationStrategy.instantiate 方法实现

java 复制代码
// SimpleInstantiationStrategy.java
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
    // 如果bean定义中没有缓存的构造方法,通过反射获取
    if (!bd.hasConstructorArgumentValues()) {
        Constructor<?> constructorToUse;
        synchronized (bd.constructorArgumentLock) {
            constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
            if (constructorToUse == null) {
                final Class<?> clazz = bd.getBeanClass();
                // 通过反射获取无参构造方法
                constructorToUse = clazz.getDeclaredConstructor();
                // 赋值给bean定义(缓存构造方法,避免重复反射)
                bd.resolvedConstructorOrFactoryMethod = constructorToUse;
            }
        }
        // 通过BeanUtils.instantiateClass方法生成实例
        return BeanUtils.instantiateClass(constructorToUse);
    }
    else {
        // 有构造参数的情况(本次不关注)
    }
}

作用:通过反射创建 Bean 实例。

处理过程

  1. 使用 SimpleInstantiationStrategy 创建实例。
  2. 通过反射 clazz.getDeclaredConstructor() 获取构造方法,并赋值给 Bean 定义(缓存构造方法,避免重复反射)。
  3. 通过 BeanUtils.instantiateClass() 方法生成实例。
  4. 最后封装在 BeanWrapperImpl 中返回。

BeanWrapper 的作用BeanWrapper 提供了对 Bean 属性的统一访问接口,支持属性值的设置和获取。

步骤 21:设置 resolvedTargetType

源码位置AbstractAutowireCapableBeanFactory.doCreateBean()

java 复制代码
// AbstractAutowireCapableBeanFactory.java
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);
    Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    
    // 步骤21:设置resolvedTargetType
    mbd.resolvedTargetType = beanType;
    
    // ... 后续步骤
}

作用 :将解析得到的 Class 类型设置到 Bean 定义的 resolvedTargetType 属性中。

  • 这样后续可以直接使用这个类型,而不需要再次解析。
步骤 22:应用 MergedBeanDefinitionPostProcessor

源码位置AbstractAutowireCapableBeanFactory.doCreateBean()

java 复制代码
// AbstractAutowireCapableBeanFactory.java
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // ... 前面的步骤
    
    // 步骤22:应用MergedBeanDefinitionPostProcessor(本次不关注)
    // applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
    // 对于UserService,这段逻辑走进去后什么也没做(没有配置相关的后置处理器)
    // 后续需要研究什么情况下会有逻辑(例如:AutowiredAnnotationBeanPostProcessor会在这里处理@Autowired注解)
    
    // ... 后续步骤
}

说明 :应用 MergedBeanDefinitionPostProcessor 后置处理器。对于 UserService,这段逻辑走进去后什么也没做(没有配置相关的后置处理器)。

步骤 23:提前暴露 Bean(解决循环依赖)

源码位置AbstractAutowireCapableBeanFactory.doCreateBean()

java 复制代码
// AbstractAutowireCapableBeanFactory.java
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // ... 前面的步骤
    
    // 步骤23:提前暴露Bean(解决循环依赖)
    boolean earlySingletonExposure = (mbd.isSingleton() && 
            this.allowCircularReferences && 
            isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }
    
    // ... 后续步骤
}

addSingletonFactory 方法实现

java 复制代码
// DefaultSingletonBeanRegistry.java
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
    synchronized (this.singletonObjects) {
        if (!this.singletonObjects.containsKey(beanName)) {
            // 将封装的ObjectFactory放入三级缓存singletonFactories中
            this.singletonFactories.put(beanName, singletonFactory);
            // 从二级缓存earlySingletonObjects中移除该beanName(如果存在)
            this.earlySingletonObjects.remove(beanName);
            // 在registeredSingletons中添加该beanName(记录已注册的单例Bean)
            this.registeredSingletons.add(beanName);
        }
    }
}

作用:如果允许提前暴露,将 Bean 的工厂对象放入三级缓存,用于解决循环依赖。

处理条件

  • 是单例 Bean
  • 允许循环依赖(allowCircularReferencestrue
  • Bean 正在创建中

处理过程

  1. 将封装的 ObjectFactory 放入三级缓存 singletonFactories 中。
  2. 从二级缓存 earlySingletonObjects 中移除该 beanName(如果存在)。
  3. registeredSingletons 中添加该 beanName(记录已注册的单例 Bean)。
步骤 24:填充 Bean 属性

源码位置AbstractAutowireCapableBeanFactory.doCreateBean()

java 复制代码
// AbstractAutowireCapableBeanFactory.java
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // ... 前面的步骤
    
    // 步骤24:填充Bean属性(本次不关注具体实现)
    // populateBean(beanName, mbd, instanceWrapper);
    // 对于UserService,大部分逻辑都跳过了(没有配置属性注入)
    // 后续需要研究这个方法的作用,特别是属性注入的具体实现
    
    Object exposedObject = bean;
    try {
        populateBean(beanName, mbd, instanceWrapper);
        // ... 后续步骤
    }
}

说明 :填充 Bean 的属性值(依赖注入)。对于 UserService,大部分逻辑都跳过了(没有配置属性注入)。后续需要研究这个方法的作用,特别是属性注入的具体实现。

步骤 25:调用 Aware 方法

源码位置AbstractAutowireCapableBeanFactory.initializeBean()

java 复制代码
// AbstractAutowireCapableBeanFactory.java
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    // 步骤25:调用Aware方法(本次不关注)
    // invokeAwareMethods(beanName, bean);
    // 由于UserService没有实现任何Aware接口(如BeanNameAware、BeanFactoryAware等),所以跳过
    
    if (bean instanceof Aware) {
        if (bean instanceof BeanNameAware) {
            ((BeanNameAware) bean).setBeanName(beanName);
        }
        if (bean instanceof BeanClassLoaderAware) {
            ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
        }
        if (bean instanceof BeanFactoryAware) {
            ((BeanFactoryAware) bean).setBeanFactory(this);
        }
    }
    
    // ... 后续步骤
}

说明 :如果 Bean 实现了 Aware 接口,调用相应的 setXxx() 方法。由于 UserService 没有实现任何 Aware 接口,所以跳过。

步骤 26:应用 BeanPostProcessor(初始化前)

源码位置AbstractAutowireCapableBeanFactory.initializeBean()

java 复制代码
// AbstractAutowireCapableBeanFactory.java
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    // ... 前面的步骤
    
    // 步骤26:应用BeanPostProcessor(初始化前)(本次不关注)
    // Object wrappedBean = bean;
    // if (mbd == null || !mbd.isSynthetic()) {
    //     wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    // }
    // 对于UserService,没有配置任何BeanPostProcessor,所以没有做任何事
    
    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }
    
    // ... 后续步骤
}

说明 :在 Bean 初始化之前,应用所有 BeanPostProcessorpostProcessBeforeInitialization() 方法。对于 UserService,没有配置任何 BeanPostProcessor,所以没有做任何事。

步骤 27:调用初始化方法

源码位置AbstractAutowireCapableBeanFactory.initializeBean()

java 复制代码
// AbstractAutowireCapableBeanFactory.java
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    // ... 前面的步骤
    
    // 步骤27:调用初始化方法
    try {
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
        // ... 异常处理
    }
    
    // ... 后续步骤
}

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
        // 如果Bean实现了InitializingBean接口,调用afterPropertiesSet()方法
        ((InitializingBean) bean).afterPropertiesSet();
    }
    
    if (mbd != null && bean.getClass() != NullBean.class) {
        String initMethodName = mbd.getInitMethodName();
        if (StringUtils.hasLength(initMethodName) &&
                !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                !mbd.isExternallyManagedInitMethod(initMethodName)) {
            // 如果配置了init-method,调用指定的初始化方法
            invokeCustomInitMethod(beanName, bean, mbd);
        }
    }
}

作用:调用 Bean 的初始化方法。

处理过程

  1. 如果 Bean 实现了 InitializingBean 接口,调用 afterPropertiesSet() 方法。
  2. 如果配置了 init-method,调用指定的初始化方法。
  • 对于 UserService,没有配置 init-method,也没有实现 InitializingBean,所以没有做任何事。
步骤 28:应用 BeanPostProcessor(初始化后)

源码位置AbstractAutowireCapableBeanFactory.initializeBean()

java 复制代码
// AbstractAutowireCapableBeanFactory.java
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    // ... 前面的步骤
    
    // 步骤28:应用BeanPostProcessor(初始化后)(本次不关注)
    // if (mbd == null || !mbd.isSynthetic()) {
    //     wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    // }
    // 对于UserService,没有配置任何BeanPostProcessor,所以没有做任何事
    
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }
    
    return wrappedBean;
}

说明 :在 Bean 初始化之后,应用所有 BeanPostProcessorpostProcessAfterInitialization() 方法。对于 UserService,没有配置任何 BeanPostProcessor,所以没有做任何事。

步骤 29:注册单例 Bean

源码位置DefaultSingletonBeanRegistry.getSingleton(String, ObjectFactory)

java 复制代码
// DefaultSingletonBeanRegistry.java
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    synchronized (this.singletonObjects) {
        // ... 前面的步骤(创建Bean)
        
        // 步骤29:注册单例Bean
        afterSingletonCreation(beanName);
        addSingleton(beanName, singletonObject);
        
        return singletonObject;
    }
}

protected void addSingleton(String beanName, Object singletonObject) {
    synchronized (this.singletonObjects) {
        // 将Bean实例放入一级缓存singletonObjects中
        this.singletonObjects.put(beanName, singletonObject);
        // 从三级缓存singletonFactories中删除该beanName
        this.singletonFactories.remove(beanName);
        // 从二级缓存earlySingletonObjects中删除该beanName
        this.earlySingletonObjects.remove(beanName);
        // 在registeredSingletons中添加该beanName(如果不存在)
        this.registeredSingletons.add(beanName);
    }
}

作用:将创建好的单例 Bean 注册到单例缓存中。

处理过程

  1. 将 Bean 实例放入一级缓存 singletonObjects 中。
  2. 从三级缓存 singletonFactories 中删除该 beanName
  3. 从二级缓存 earlySingletonObjects 中删除该 beanName
  4. registeredSingletons 中添加该 beanName(如果不存在)。

缓存清理:Bean 创建完成后,不再需要工厂对象和提前暴露的对象,所以从三级和二级缓存中删除,只保留在一级缓存中。

步骤 30:完成单例 Bean 注册

源码位置DefaultSingletonBeanRegistry.addSingleton()

java 复制代码
// DefaultSingletonBeanRegistry.java
protected void addSingleton(String beanName, Object singletonObject) {
    synchronized (this.singletonObjects) {
        // 步骤30:将singletonObjects放入单例,其他缓存删除,registeredSingletons中add
        // 1. 将Bean实例放入一级缓存singletonObjects中
        this.singletonObjects.put(beanName, singletonObject);
        // 2. 从三级缓存singletonFactories中删除该beanName
        this.singletonFactories.remove(beanName);
        // 3. 从二级缓存earlySingletonObjects中删除该beanName
        this.earlySingletonObjects.remove(beanName);
        // 4. 在registeredSingletons中添加该beanName(如果不存在)
        this.registeredSingletons.add(beanName);
    }
}

作用:完成单例 Bean 的最终注册,清理临时缓存。

具体操作

  1. 将 Bean 实例放入一级缓存 singletonObjects 中。
  2. 从三级缓存 singletonFactories 中删除该 beanName
  3. 从二级缓存 earlySingletonObjects 中删除该 beanName
  4. registeredSingletons 中添加该 beanName(如果不存在)。

说明:这是 Bean 创建流程的最后一步,确保 Bean 实例被正确注册到单例缓存中,并清理所有临时缓存。


总结 :通过以上 30 个步骤,我们完整地追踪了 UserService 这个最简单的 Bean 从获取到创建的全过程。整个过程涉及了 Bean 名称转换、缓存查找、Bean 定义获取、实例创建、属性填充、初始化等多个环节。对于更复杂的 Bean(如有依赖注入、初始化方法、后置处理器等),会在相应的步骤中执行额外的逻辑。


相关推荐
巴塞罗那的风2 小时前
golang协程泄漏排查实战
开发语言·后端·golang
派大鑫wink2 小时前
【Day21】NIO入门:通道、缓冲区与非阻塞IO基础
java·开发语言
ziyue75752 小时前
idea将配置移动到自定义位置
java·intellij-idea·idea·软件
quant_19862 小时前
BTC 行情预警系统实战教程
开发语言·后端·python·websocket·程序人生·金融
南汐以墨2 小时前
UI自动化测试指南(一):浅解概念
java·测试工具
不能只会打代码2 小时前
力扣--1970. 你能穿过矩阵的最后一天(Java)
java·算法·leetcode·二分查找·力扣·bfs·最后可行时间
少年执笔2 小时前
android新版TTS无法进行语音播报
android·java
superman超哥2 小时前
Rust 日志级别与结构化日志:生产级可观测性实践
开发语言·后端·rust·可观测性·rust日志级别·rust结构化日志
每天早点睡2 小时前
continue语句
后端