Spring

Spring Bean 生命周期

深入理解 Spring Bean 从创建到销毁的完整生命周期,包括实例化、属性赋值、初始化和销毁四大阶段

#Spring#IoC#Bean#生命周期

Spring Bean 的生命周期

Spring 不仅仅是 new 了一个对象,它是在对象创建的前、中、后各个环节都留出了窗口,允许你像做手术一样精准地修改这个对象的行为。


一、 概览:Bean 生命周期的四大阶段

如果把 Spring Bean 比作一个人 🧍,它的生命周期可以粗略地分为这四个主要阶段:

  1. 实例化 (Instantiation):
  • 相当于“出生”。Spring 容器通过反射机制在堆内存中申请空间,创建一个原始的对象。此时,对象中的属性还是默认值(如 null)。
  1. 属性赋值 (Populate Properties):
  • 相当于“成长的补给”。Spring 将配置文件中定义的属性值、或者通过 @Autowired 注解引用的其他依赖 Bean,注入到这个对象中。
  1. 初始化 (Initialization):
  • 相当于“成年礼/岗前培训”。这是最复杂的一步,对象虽然有了数据,但可能还需要进行各种配置检查、连接数据库资源、或者被 AOP 代理包装,这一步完成后,Bean 才是真正可用的。
  1. 销毁 (Destruction):
  • 相当于“退休/离世”。当容器关闭时,需要清理资源(如关闭数据库连接、IO 流)。

二、 详细执行顺序

在上述四大阶段之间,Spring 穿插了非常多的 扩展点(Hook),让开发者可以介入 Bean 的创建过程。以下是严格的执行顺序:

1. 实例化阶段

  • Step 1: 实例化 Bean (Instantiation)
  • 调用构造函数(Constructor)。

2. 属性赋值阶段

  • Step 2: 填充属性 (Populate Properties)
  • 调用 Setter 方法或直接注入字段(Dependency Injection)。

3. 初始化阶段(核心)

Step 3: 检查 Aware 接口 (Aware Interfaces)

  • 如果 Bean 实现了 BeanNameAware,调用 setBeanName(告诉 Bean 它自己的名字)。
  • 如果 Bean 实现了 BeanFactoryAware,调用 setBeanFactory(让 Bean 能获取到工厂本身)。
  • (注:还有其他 Aware,如 ApplicationContextAware)

Step 4: BeanPostProcessor - 前置处理 (Before)

  • 关键点:调用 BeanPostProcessor.postProcessBeforeInitialization()
  • 这是容器级别的扩展,对 所有 Bean 都生效。通常用于修改 Bean 的原始属性。

Step 5: 初始化方法 (Initialization Methods)

  • a. 调用 @PostConstruct 注解的方法(JSR-250 标准)。
  • b. 调用 InitializingBean.afterPropertiesSet() 方法。
  • c. 调用 XML 中配置的 init-method@Bean(initMethod = "...") 指定的方法。

Step 6: BeanPostProcessor - 后置处理 (After)

  • 关键点:调用 BeanPostProcessor.postProcessAfterInitialization()
  • AOP 的发生地:Spring 的 AOP 动态代理通常是在这一步完成的。如果需要代理,这里返回的将是代理对象,而不是原始对象。

4. 使用阶段

Step 7: Bean 准备就绪

  • 此时 Bean 已经存在于 Spring 容器中,可以被其他对象引用和使用了。

5. 销毁阶段

Step 8: 销毁方法 (Destruction Methods)

  • a. 调用 @PreDestroy 注解的方法。
  • b. 调用 DisposableBean.destroy() 接口方法。
  • c. 调用自定义的 destroy-method

三、 代码实例演示

为了直观地看到这个顺序,我们写一个简单的 Spring Boot 例子。

1. 定义一个全功能的 Bean

这个 Bean 实现了生命周期中涉及的大部分接口。

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class LifeCycleBean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {

    private String name;

    public LifeCycleBean() {
        System.out.println("1. [实例化] 调用构造函数");
    }

    public void setName(String name) {
        this.name = name;
        System.out.println("2. [属性赋值] 调用 Setter 方法设置属性: " + name);
    }

    @Override
    public void setBeanName(String s) {
        System.out.println("3. [Aware接口] 调用 BeanNameAware.setBeanName: " + s);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("4. [Aware接口] 调用 BeanFactoryAware.setBeanFactory");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("5. [Aware接口] 调用 ApplicationContextAware.setApplicationContext");
    }
    
    // 注意:Step 6 (PostProcessor Before) 在外部类中

    @PostConstruct
    public void myPostConstruct() {
        System.out.println("7. [初始化] 调用 @PostConstruct 注解方法");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("8. [初始化] 调用 InitializingBean.afterPropertiesSet()");
    }

    public void myInitMethod() {
        System.out.println("9. [初始化] 调用自定义 init-method");
    }
    
    // 注意:Step 10 (PostProcessor After) 在外部类中

    @PreDestroy
    public void myPreDestroy() {
        System.out.println("11. [销毁] 调用 @PreDestroy 注解方法");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("12. [销毁] 调用 DisposableBean.destroy()");
    }

    public void myDestroyMethod() {
        System.out.println("13. [销毁] 调用自定义 destroy-method");
    }
}

2. 定义一个后置处理器 (BeanPostProcessor)

这是一个 拦截器,会拦截所有的 Bean。

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if ("lifeCycleBean".equals(beanName)) {
            System.out.println("6. [PostProcessor] postProcessBeforeInitialization (初始化前置)");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if ("lifeCycleBean".equals(beanName)) {
            System.out.println("10. [PostProcessor] postProcessAfterInitialization (初始化后置 - AOP代理常在此处)");
        }
        return bean;
    }
}

3. 配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class LifeCycleConfig {

    @Bean(initMethod = "myInitMethod", destroyMethod = "myDestroyMethod")
    public LifeCycleBean lifeCycleBean() {
        LifeCycleBean bean = new LifeCycleBean();
        bean.setName("设置 name 属性");
        return bean;
    }
}


上面代码比较占位置,这里贴一个 tab 标签展示风格的

四、 运行结果

当你启动并关闭 Spring 容器时,控制台将严格按照以下顺序打印:

1. [实例化] 调用构造函数
2. [属性赋值] 调用 Setter 方法设置属性: 设置 name 属性
3. [Aware接口] 调用 BeanNameAware.setBeanName: lifeCycleBean
4. [Aware接口] 调用 BeanFactoryAware.setBeanFactory
5. [Aware接口] 调用 ApplicationContextAware.setApplicationContext
6. [PostProcessor] postProcessBeforeInitialization (初始化前置)
7. [初始化] 调用 @PostConstruct 注解方法
8. [初始化] 调用 InitializingBean.afterPropertiesSet()
9. [初始化] 调用自定义 init-method
10. [PostProcessor] postProcessAfterInitialization (初始化后置 - AOP代理常在此处)

... (此时 Bean 可在应用中使用) ...
... (容器关闭) ...

11. [销毁] 调用 @PreDestroy 注解方法
12. [销毁] 调用 DisposableBean.destroy()
13. [销毁] 调用自定义 destroy-method

五、 动画演示

Spring Bean 生命周期

从实例化到销毁的全过程深度解析

实例化

1. 实例化 (Instantiation)

调用构造函数 Constructor,在堆内存中申请空间。

属性赋值

2. 属性赋值 (Populate)

调用 Setter 或字段注入,填充 @Autowired 依赖。

初始化
核心初始化流程

3. Aware 接口回调

BeanNameAware, BeanFactoryAware... 通知 Bean 自身环境信息。

4. BeanPostProcessor (Before)

初始化前置处理。修改原始 Bean 的最后机会。

5. 初始化方法

@PostConstruct → afterPropertiesSet() → init-method

6. BeanPostProcessor (After)

AOP 关键点。动态代理通常在此处生成。

7. Bean 准备就绪

Bean 进入容器单例池,可被应用使用。

销毁

8. 销毁 (Destruction)

容器关闭。@PreDestroy → DisposableBean → destroy-method

进度: 0 / 8 | 状态:未开始
Console Output
// 请选择自动演示或手动下一步