【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(如有依赖注入、初始化方法、后置处理器等),会在相应的步骤中执行额外的逻辑。


相关推荐
Penge6668 小时前
Go 接口编译期断言
后端
我是一颗柠檬8 小时前
【MySQL全面教学】MySQL面试高频考点汇总Day15(2026年)
数据库·后端·mysql·面试
橙淮9 小时前
并发编程(六)
java·jvm
拽着尾巴的鱼儿9 小时前
springboot openfeign 自定义feign 接口重试机制
java·spring boot·后端
白露与泡影9 小时前
2026大厂Java面试题大全!牛客网最新版
java·开发语言
Ceelog9 小时前
久坐党自救指南:屏幕前 8 小时,身体到底在经历什么
前端·后端
EntyIU10 小时前
JVM内存与GC笔记
java·jvm·笔记
XS03010610 小时前
并发编程 六
java·后端
yaoxin52112310 小时前
419. 现代 Java IO 最佳实践 - 写入文本文件
java·windows·python
雪宫街道10 小时前
synchronized 锁的范围:对象锁、类锁与代码块锁
java·jvm·后端·面试