spring bean的生命周期详解

Spring Bean 的生命周期是指从 Bean 的定义加载 开始,经历 实例化、属性赋值、初始化,直到 容器销毁 的完整过程。理解生命周期的核心在于掌握 IOC(控制反转)DI(依赖注入) 的执行顺序,以及如何在各个阶段进行干预。

以下是 Spring Bean 生命周期的详细拆解,分为 4 个主要阶段13 个关键步骤


一、 生命周期全景图(核心流程)

为了直观理解,先看这张核心流程图:

1. 实例化 (Instantiation)
   ↓
2. 填充属性 (Populate Properties)
   ↓
3. 设置 Aware 接口 (Aware Interfaces)
   ↓
4. BeanPostProcessor 前置处理 (Before Initialization)
   ↓
5. 初始化 (Initialization)
   ├─ @PostConstruct
   ├─ InitializingBean.afterPropertiesSet()
   └─ 自定义 init-method
   ↓
6. BeanPostProcessor 后置处理 (After Initialization)
   ↓
7. Bean 就绪 (Ready for Use)
   ↓
8. 销毁 (Destruction)
   ├─ @PreDestroy
   ├─ DisposableBean.destroy()
   └─ 自定义 destroy-method

二、 详细步骤拆解

第一阶段:实例化与属性注入
步骤名称说明
1实例化 Bean容器通过反射调用构造方法创建 Bean 实例(此时对象刚出生,属性全是默认值)。
2设置属性值 (DI)容器解析配置(XML/@Component/@Bean),通过 Setter 或字段注入将依赖的 Bean 注入进来。
第二阶段:Aware 接口回调(感知容器)

如果 Bean 实现了 Aware 接口,Spring 会回调这些方法,让 Bean 感知到容器的存在。

步骤接口作用
3BeanNameAware获取 Bean 在容器中的 ID。
4BeanFactoryAware获取创建它的 BeanFactory。
5ApplicationContextAware获取 Spring 上下文(最常用,可获取环境配置等)。
第三阶段:初始化前置处理(BeanPostProcessor)

这是 Spring 扩展点的核心,允许在 Bean 初始化前后插入自定义逻辑(如 AOP 代理就是在这里生成的)。

步骤名称说明
6BeanPostProcessor.postProcessBeforeInitialization在所有初始化方法之前执行。例如 @PostConstruct 注解的处理器就是在此处生效。
第四阶段:初始化(Initialization)

这是 Bean 正式投入使用前的最后一步,用于校验配置或启动资源。

步骤名称说明
7@PostConstructJSR-250 标准注解,标注的方法会被调用。
8InitializingBean.afterPropertiesSet()实现该接口的 Bean 必须重写此方法。
9自定义 init-methodXML 中 init-method@Bean(initMethod="...") 指定的方法。

注意:如果同时存在,@PostConstruct 早于 InitializingBean,早于 init-method

第五阶段:初始化后置处理(AOP 关键)
步骤名称说明
10BeanPostProcessor.postProcessAfterInitialization初始化完成后执行。Spring AOP 就是在此处创建代理对象并返回,替换原始对象。
第六阶段:使用与销毁
步骤名称说明
11Bean 就绪Bean 存储在单例池中,等待被程序调用。
12销毁回调容器关闭时触发,顺序与初始化相反:
1. @PreDestroy
2. DisposableBean.destroy()
3. 自定义 destroy-method

三、 代码示例验证顺序

@Component
public class LifeCycleBean implements BeanNameAware, InitializingBean, DisposableBean {

    public LifeCycleBean() {
        System.out.println("1. 构造方法执行");
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("2. BeanNameAware.setBeanName: " + name);
    }

    @PostConstruct
    public void postConstruct() {
        System.out.println("3. @PostConstruct");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("4. InitializingBean.afterPropertiesSet");
    }

    public void initMethod() {
        System.out.println("5. 自定义 init-method");
    }

    @PreDestroy
    public void preDestroy() {
        System.out.println("6. @PreDestroy");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("7. DisposableBean.destroy");
    }

    public void destroyMethod() {
        System.out.println("8. 自定义 destroy-method");
    }
}

输出结果:

1. 构造方法执行
2. BeanNameAware.setBeanName: lifeCycleBean
3. @PostConstruct
4. InitializingBean.afterPropertiesSet
5. 自定义 init-method
...
6. @PreDestroy
7. DisposableBean.destroy
8. 自定义 destroy-method

四、 关键机制与面试考点

1. BeanPostProcessor 的作用域

BeanPostProcessor 是针对所有 Bean 生效的。如果你定义了多个 BeanPostProcessor,可以通过实现 Ordered 接口来控制执行顺序。

2. 循环依赖如何解决?

Spring 通过 三级缓存 解决单例 Bean 的循环依赖(Setter/Field 注入):

  • 一级缓存:存放成品 Bean。
  • 二级缓存:存放早期的 Bean 引用(未完成初始化的)。
  • 三级缓存:存放 ObjectFactory(用于生成早期引用,特别是解决 AOP 代理问题)。

注意:构造器注入和多例(Prototype)模式无法解决循环依赖。

3. 单例 vs 原型 (Prototype)
  • Singleton(默认):容器启动时创建,生命周期完全由容器管理,销毁时调用销毁方法。
  • Prototype:每次获取时创建,容器只负责创建和初始化,不负责销毁,销毁方法需要用户自行调用。

五、 视野拓展:生命周期与 Spring Boot Starter

Spring Boot Starter 中生命周期相关:

  • 自动配置类 (XxxAutoConfiguration) 本质上就是一个 @Configuration 类,它内部定义的 @Bean 都会经历上述生命周期。
  • 条件注解 (@ConditionalOnMissingBean) 通常在 初始化阶段 之前生效,决定了某个 Bean 是否会被创建。
  • 健康指示器 (HealthIndicator)指标收集器 通常在 初始化阶段 注册到监控系统中。

掌握 Bean 生命周期,是理解 Spring Boot 自动装配原理和进行高级扩展(如自定义 Starter、AOP 切面)的基础。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值