Spring源码 第二篇:Spring Bean 生命周期:从实例化到销毁全源码解析

一、Bean 生命周期总览

Spring Bean 的生命周期可以概括为以下几个核心阶段:

  1. 实例化 (Instantiation)
  2. 属性填充 (Populate Properties / Dependency Injection)
  3. 初始化 (Initialization)
  4. 销毁 (Destruction)

一个更直观的流程图如下:

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

我们代码里通常这样获取 Bean:

java 复制代码
UserService userService = context.getBean(UserService.class);

其真实的源码调用链如下:

java 复制代码
// AbstractApplicationContext
public <T> T getBean(Class<T> requiredType) {
    return getBeanFactory().getBean(requiredType);
}

// 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
public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args) throws BeansException {
    return this.doGetBean(name, requiredType, args, false);
}

最终走到核心方法:

java 复制代码
// AbstractBeanFactory
public Object getBean(String name) {
    return doGetBean(name, null, null, false);
}

三、核心:doGetBean 全流程

java 复制代码
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);    
}

四、createBean 真实入口

java 复制代码
// 类: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

java 复制代码
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

java 复制代码
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;
}

五、什么时候才会执行 createBean?

只有以下情况,才会进入 createBean 流程:

java 复制代码
sharedInstance = getSingleton(beanName, () -> createBean(...));

具体场景包括:

  1. 容器 refresh() 内部 preInstantiateSingletons():容器启动时,遍历创建所有非懒加载的单例 Bean。
  2. Bean 上加了 @Lazy :第一次手动 getBean() 时才创建。
  3. 作用域是 @Scope("prototype") :每次 getBean() 都创建。
  4. Bean 被销毁后,再次获取:需要重新创建。

六、简单总结

  1. Spring 容器启动时,会自动把所有单例 Bean 创建好。
  2. 你手动 getBean() 只是从一级缓存拿现成对象。
  3. 真正的创建流程只发生在容器内部第一次实例化。
  4. 生命周期完整链路:实例化 → 填充 → Aware → 前置 → 初始化 → 后置 → 入池

核心步骤流程图


  1. 获取 BeanName

从一级缓存 singletonObjects 尝试获取
缓存是否存在?
直接从缓存返回成品 Bean
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

相关推荐
武子康1 分钟前
Java-07 深入浅出 MyBatis数据库一对多关系模型实战:表结构设计与查询实现
java·后端
花椒技术1 小时前
企业内部 Agent 落地复盘:Gateway、Skill 和二次确认如何串起受控业务执行
后端·agent·ai编程
REDcker2 小时前
Linux OverlayFS详解
java·linux·运维
Royzst2 小时前
xml知识点
java·服务器·前端
我是一颗柠檬3 小时前
【MySQL全面教学】MySQL事务与ACID Day9(2026年)
数据库·后端·mysql
枕星而眠3 小时前
数据结构八大排序详解(一):四大简单排序
c语言·数据结构·c++·后端
IT_陈寒3 小时前
React useEffect闭包陷阱差点把我整失业了
前端·人工智能·后端
鱼鳞_3 小时前
苍穹外卖-Day08(缓存套餐)
java·redis·缓存
过期动态3 小时前
【LeetCode 热题 100】移动零
java·数据结构·算法·leetcode·职场和发展·rabbitmq
苍何3 小时前
爆肝两周,我把 Codex 最全实战指南开源了
后端