找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2564

积分

0

好友

342

主题
发表于 1 小时前 | 查看: 2| 回复: 0

上一篇我们分析了 IOC 容器的启动、包扫描以及 BeanDefinition 的注册流程。容器拿到“设计图纸”后,下一步就是按图索骥,开始生产 Bean 了。本篇将深入 Spring 的核心腹地,完整拆解一个 Bean 从无到有,再到销毁的整个生命周期源码。

一、Bean 生命周期总览

在深入代码之前,我们先从宏观上把握整个流程。当一个 BeanDefinition 已经注册到容器后,其生命周期主线如下:

BeanDefinition 已存在
        ↓
getBean(beanName)
        ↓
createBean() → 创建 Bean
        ↓
【1】实例化(newInstance / 构造器)
        ↓
【2】填充属性(依赖注入 @Autowired)
        ↓
【3】执行 Aware 接口
        ↓
【4】执行 BeanPostProcessor 前置
        ↓
【5】执行初始化方法(afterPropertiesSet / @PostConstruct)
        ↓
【6】执行 BeanPostProcessor 后置(AOP 在此植入)
        ↓
成品 Bean 放入单例池 singletonObjects
        ↓
容器关闭
        ↓
【7】执行销毁方法(destroy / @PreDestroy)

二、入口:一切从 getBean() 开始

我们通常这样从容器中获取一个 Bean:

UserService userService = context.getBean(UserService.class);

这行代码背后的源码调用链非常清晰。入口在 AbstractApplicationContext

// AbstractApplicationContext
public <T> T getBean(Class<T> requiredType) {
    return getBeanFactory().getBean(requiredType);
}

紧接着,请求被传递到 DefaultListableBeanFactory

// DefaultListableBeanFactory
public <T> T getBean(Class<T> requiredType) throws BeansException {
    return this.getBean(requiredType, (Object[])null);
}

public <T> T getBean(Class<T> requiredType, @Nullable Object... args) throws BeansException {
        Assert.notNull(requiredType, "Required type must not be null");
        Object resolved = this.resolveBean(ResolvableType.forRawClass(requiredType), args, false);
        if (resolved == null) {
            throw new NoSuchBeanDefinitionException(requiredType);
        } else {
            return resolved;
        }
}

private <T> T resolveBean(ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) {
        NamedBeanHolder<T> namedBean = this.resolveNamedBean(requiredType, args, nonUniqueAsNull);
     // ........省略
}

private <T> NamedBeanHolder<T> resolveNamedBean(ResolvableType requiredType, @Nullable Object[] args, boolean nonUniqueAsNull) throws BeansException {
    // ........省略
    if (candidateNames.length == 1) {
            return this.resolveNamedBean(candidateNames[0], requiredType, args);
     }//.........省略
}

private <T> NamedBeanHolder<T> resolveNamedBean(String beanName, ResolvableType requiredType, @Nullable Object[] args) throws BeansException {
        Object bean = this.getBean(beanName, (Class)null, args);
        return bean instanceof NullBean ? null : new NamedBeanHolder(beanName, this.adaptBeanInstance(beanName, bean, requiredType.toClass()));
    }

最终,调用链会抵达 AbstractBeanFactory,这里是真正的起点:

// AbstractBeanFactory
public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args) throws BeansException {
        return this.doGetBean(name, requiredType, args, false);
    }

其最基础的 getBean(String name) 方法也指向同一个核心方法:

// AbstractBeanFactory
public Object getBean(String name) {
    return doGetBean(name, null, null, false);
}

三、核心:doGetBean 全流程

doGetBean 方法是整个获取逻辑的调度中心,它决定了是直接返回缓存对象,还是启动创建流程。

protected <T> T doGetBean(
        String name, @Nullable Class<T> requiredType,
        @Nullable Object[] args, boolean typeCheckOnly) {
    // 1. 标准化 beanName(去掉 & 前缀)
    String beanName = transformedBeanName(name);
    // 2. 从一级缓存拿
    Object sharedInstance = getSingleton(beanName);
    // ==========================================
    // 【你手动调用时,这里一定不为 null】
    // 因为容器启动时已经创建好了
    // ==========================================
    if (sharedInstance != null && args == null) {
        Object beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }
    // ... 省略父工厂、原型、自定义 scope ...
    // ==========================================
    // 【只有缓存为空,才会走到这里创建】
    // 场景:
    // 1. 容器内部第一次创建
    // 2. @Lazy 第一次调用
    // 3. prototype 每次调用
    // ==========================================
    if (mbd.isSingleton()) {
        sharedInstance = getSingleton(beanName, () -> {
            try {
                // ↓↓↓ 真正创建 Bean ↓↓↓
                return createBean(beanName, mbd, args);
            } catch (BeansException ex) {
                destroySingleton(beanName);
                throw ex;
            }
        });
        Object beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);

    }
    // ... prototype 分支 ...
        return adaptBeanInstance(name, beanInstance, requiredType);
}

可以看到,对于单例 Bean,创建逻辑被包装在一个 ObjectFactory(Lambda 表达式)中,传递给了 getSingleton 方法。这正是 Spring 解决循环依赖的关键设计之一。

四、createBean 真实入口

当需要创建 Bean 时,createBean 方法被调用,它主要做一些准备工作,真正的创建动作委托给了 doCreateBean

// 类:AbstractAutowireCapableBeanFactory
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {
    // ... 准备工作、class 加载、方法重写等 ...
    // ↓↓↓ 核心:真正创建逻辑在 doCreateBean ↓↓↓
    Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    return beanInstance;
}

五、doCreateBean:生命周期的三个阶段

doCreateBean 方法是 Bean 生命周期的核心体现,它清晰地划分为三个阶段:

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // ====================== ① 实例化 Bean ======================
    // 调用构造方法创建对象,生成 BeanWrapper
    BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);
    Object bean = instanceWrapper.getWrappedInstance();
    // ====================== ② 填充属性 ======================
    // 依赖注入:@Autowired、@Resource 在这里处理
    populateBean(beanName, mbd, instanceWrapper);
    // ====================== ③ 初始化 Bean ======================
    // Aware + BeanPostProcessor 前后置 + 初始化方法
    Object exposedObject = initializeBean(beanName, bean, mbd);
    return exposedObject;
}

六、initializeBean:初始化的精细步骤

第三阶段 initializeBean 内部又包含了我们熟知的经典步骤:

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    // 1. 执行各种 Aware 接口
    invokeAwareMethods(beanName, bean);
    // 2. BeanPostProcessor 前置处理
    Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);
    // 3. 执行初始化方法
    // @PostConstruct / afterPropertiesSet / init-method
    invokeInitMethods(beanName, wrappedBean, mbd);
    // 4. BeanPostProcessor 后置处理(AOP 代理在此生成)
    wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    return wrappedBean;
}

@Autowired 这类依赖注入发生在第二阶段 populateBean,而 @PostConstructInitializingBean.afterPropertiesSet 则发生在第三阶段的 invokeInitMethods 中。AOP 代理对象的生成是在第四步,由 BeanPostProcessor 后置处理器(AnnotationAwareAspectJAutoProxyCreator)完成的。

七、何时会触发 Bean 的创建?

并不是每次 getBean() 都会走创建流程。只有在以下情况,才会执行 createBean

sharedInstance = getSingleton(beanName, () -> createBean(...));
  1. 容器内部第一次初始化:在 refresh() 方法的 finishBeanFactoryInitialization 阶段,通过 preInstantiateSingletons() 遍历创建所有非懒加载的单例 Bean。
  2. 懒加载 Bean 首次被请求:Bean 上标注了 @Lazy,只有在第一次主动 getBean() 时才创建。
  3. 原型作用域的 Bean:每次 getBean() 都会创建一个新的实例。
  4. Bean 被销毁后再次获取:这种情况较为罕见。

八、总结与回顾

让我们再梳理一下完整的脉络:

  1. 获取 BeanName → 从一级缓存 singletonObjects 尝试获取
  2. 缓存不存在 → 进入单例创建逻辑 getSingleton
  3. 执行 createBean → 进入真正创建入口
  4. doCreateBean 核心三阶段:
    • createBeanInstance:通过构造器实例化原生对象
    • populateBean:依赖注入,填充 @Autowired 属性
    • initializeBean:执行初始化逻辑
  5. initializeBean 内部精细步骤:
    • 执行 Aware 接口(BeanNameAware/BeanFactoryAware
    • 执行 BeanPostProcessor 前置处理
    • 执行初始化方法(@PostConstruct / afterPropertiesSet
    • 执行 BeanPostProcessor 后置处理(生成 AOP 代理)
  6. 创建完成,将成品 Bean 放入一级缓存
  7. 后续任何 getBean 均直接从单例池返回
  8. 容器关闭时,执行销毁方法(@PreDestroy / destroy

简单来说:

  • Spring 容器启动时,默认会提前初始化(预实例化)所有单例 Bean。
  • 你手动调用的 getBean(),大多数时候只是从一级缓存中获取现成的对象。
  • 真正的 Bean 创建生命周期只发生在容器内部第一次实例化时。
  • 完整的生命周期就是:实例化 → 属性填充 → Aware接口 → BeanPostProcessor前置 → 初始化方法 → BeanPostProcessor后置(AOP)→ 放入单例池。

理解这些核心步骤和源码位置,对于处理复杂的依赖注入问题、调试 Bean 创建顺序、或是编写自定义的 BeanPostProcessor 都至关重要。如果你想深入研究其他如 BeanDefinition 的解析或更底层的设计,可以查阅相关的技术文档进行系统学习。此外,在 云栈社区 的 Java 板块,也有很多开发者分享关于 Spring 核心机制的讨论和实践经验,可以作为延伸阅读。

下篇预告
在下一篇中,我们将挑战 Spring 面试中最经典、也是最难的问题之一:循环依赖与三级缓存的完整源码拆解。我们将弄清楚:

  • 为什么 Spring 默认只能解决 setter 注入的循环依赖?
  • 三级缓存每一级到底存放了什么对象?
  • “早期引用”是如何解决循环依赖的?
  • 构造器注入的循环依赖为何无法解决?



上一篇:没有AI,程序员也不会好过?拆解5重困境与破局之道
下一篇:Harness Engineering 实战解析:规范驱动开发(SDD)在 AI Coding 中的新价值
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-4-1 05:23 , Processed in 0.694052 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表