简单来说,Spring Bean的生命周期可以分为四个大的阶段:实例化 (Instantiation) -> 属性赋值 (Population) -> 初始化 (Initialization) -> 销毁 (Destruction)

下面我将详细拆解每个步骤,并提供一个流程图帮助你更好地理解。

核心生命周期流程图

flowchart TD
    A[开始创建Bean] --> B[实例化 Instantiation]
    B --> C[属性赋值 Population]
    C --> D[初始化 Initialization]
    D --> E[投入使用]
    E --> F[销毁 Destruction]
    
    subgraph B [实例化]
        B1[推断构造函数]
        B2[执行构造函数 new]
    end
    
    subgraph C [属性赋值]
        C1[依赖注入 DI]
        C2[处理 Aware 接口]
    end
    
    subgraph D [初始化]
        D1[BeanPostProcessor.postProcessBeforeInitialization]
        D2[@PostConstruct]
        D3[InitializingBean.afterPropertiesSet]
        D4[自定义 init-method]
        D5[BeanPostProcessor.postProcessAfterInitialization
AOP在此发生] end B1 --> B2 B2 --> C1 C1 --> C2 C2 --> D1 D1 --> D2 D2 --> D3 D3 --> D4 D4 --> D5 D5 --> E subgraph F [销毁容器] F1[@PreDestroy] F2[DisposableBean.destroy] F3[自定义 destroy-method] end

详细步骤解析

第一阶段:实例化 (Instantiation)

  1. 加载Bean定义:Spring容器启动时,会读取配置文件(如XML)或扫描注解(如@Component),将Bean的定义信息(BeanDefinition)加载到容器中。
  2. 推断构造函数:根据BeanDefinition中的信息,决定使用哪个构造函数来创建Bean实例(无参?有参?)。
  3. 执行构造函数:通过反射(Reflection)调用选中的构造函数,仅仅是为对象分配内存空间,生成一个“原始”的对象。此时对象的属性都是默认值(如null, 0),依赖还没有被注入

注意:如果使用了@Configuration@Bean,方法体的执行也在这一步。

第二阶段:属性赋值/填充 (Population)

  1. 依赖注入 (DI):Spring解析对象之间的依赖关系,并将所需的依赖(其他Bean、配置值等)通过反射注入到对象的属性中(例如,通过@Autowired, @Value或XML中的<property>标签)。
  2. 处理Aware接口:如果Bean实现了各种Aware接口(如BeanNameAware, BeanFactoryAware, ApplicationContextAware),Spring会回调相应的方法,将容器本身的一些组件(如Bean的名字、工厂、上下文)注入给Bean。

第三阶段:初始化 (Initialization)

这是步骤最繁杂的阶段,也是扩展点最多的阶段。
6. BeanPostProcessor前置处理:所有实现了BeanPostProcessor接口的类,会执行其postProcessBeforeInitialization()方法。这是Spring提供的一个强大的扩展点,允许你在初始化开始前对Bean进行修改。
7. 执行@PostConstruct方法:执行被@PostConstruct注解标记的方法。这是JSR-250规范提供的注解。
8. 执行InitializingBean接口:如果Bean实现了InitializingBean接口,会执行其afterPropertiesSet()方法。
9. 执行自定义初始化方法:执行在BeanDefinition中指定的自定义初始化方法(例如XML中init-method属性或@Bean(initMethod = "...")指定的方法)。
10. BeanPostProcessor后置处理:所有BeanPostProcessor会再次执行其postProcessAfterInitialization()方法。这是Spring AOP(面向切面编程)创建代理对象的关键时机! 如果Bean需要被增强(例如事务管理@Transactional),Spring会在这里为其创建一个代理对象并返回。之后容器中和开发者使用的,其实是这个代理对象,而不是原始的目标对象。

初始化顺序BeanPostProcessor.before -> @PostConstruct -> InitializingBean -> init-method -> BeanPostProcessor.after

经过以上所有步骤,Bean已经完全创建好,会被放入Singleton Bean缓存池中,等待被使用。

第四阶段:销毁 (Destruction)

当Spring容器被关闭时(例如调用applicationContext.close()),会对容器中的单例Bean进行销毁。
11. 执行@PreDestroy方法:执行被@PreDestroy注解标记的方法。这也是JSR-250规范提供的。
12. 执行DisposableBean接口:如果Bean实现了DisposableBean接口,会执行其destroy()方法。
13. 执行自定义销毁方法:执行在BeanDefinition中指定的自定义销毁方法(例如XML中destroy-method属性或@Bean(destroyMethod = "...")指定的方法)。

销毁顺序@PreDestroy -> DisposableBean -> destroy-method

总结与记忆技巧

  • 大阶段:记住 创建(实例化 -> 填充 -> 初始化) -> 使用 -> 销毁
  • 扩展点:重点关注几个重要的扩展接口和注解:
    • 影响所有BeanBeanPostProcessor(非常强大,但通常由框架实现)
    • 针对单个Bean
      • 初始化@PostConstruct (推荐) > InitializingBean > init-method
      • 销毁@PreDestroy (推荐) > DisposableBean > destroy-method
    • 获取容器信息Aware系列接口。