Spring Bean 生命周期

5 阅读5分钟

Spring Bean 生命周期,是指一个 Bean 从被容器创建,到初始化完成,再到最终销毁的整个过程。
这部分是 Spring 面试中的高频问题,因为它不仅体现你对 IoC 的理解,也会牵涉到 AOP、循环依赖、BeanPostProcessor 等底层机制。

一、Bean 生命周期的整体流程

一个 Spring Bean 的生命周期大致可以分为以下几个阶段:

  1. 实例化
  2. 属性赋值(依赖注入)
  3. 初始化
  4. 使用
  5. 销毁

但在真正面试中,不能只说这五步,因为 Spring 的生命周期远比这更细。
更完整的流程应该是下面这样。


二、Spring Bean 生命周期详细过程

1. 解析 BeanDefinition

Spring 启动时,先读取配置文件、注解、配置类等信息,把每个 Bean 解析成 BeanDefinition。

BeanDefinition 中保存了 Bean 的各种元数据,例如:

  • Bean 的类名
  • scope
  • lazy-init
  • 依赖关系
  • init-method
  • destroy-method

这一步只是“注册 Bean 的定义”,对象还没有真正创建出来。


2. 实例化 Bean

Spring 根据 BeanDefinition,通过反射创建 Bean 对象。

实例化本质上就是“构造对象”,但此时对象只是一个空壳,属性还没注入,生命周期回调也还没执行。


3. 属性赋值 / 依赖注入

Spring 对 Bean 进行依赖注入,把它依赖的其他 Bean 填充进去。

常见方式:

  • 构造器注入
  • setter 注入
  • 字段注入

这一步之后,Bean 的依赖关系基本就组装好了。


4. Aware 接口回调

如果 Bean 实现了某些 Aware 接口,Spring 会在这个阶段把容器相关信息注入给它。

常见的有:

  • BeanNameAware:拿到 Bean 名称
  • BeanFactoryAware:拿到 BeanFactory
  • ApplicationContextAware:拿到 ApplicationContext

这一阶段的作用是让 Bean 感知 Spring 容器环境。


5. BeanPostProcessor 前置处理

Spring 会调用所有注册的 BeanPostProcessor 的前置方法:

postProcessBeforeInitialization()

这一步发生在真正初始化方法之前。

常见用途:

  • 对 Bean 做额外加工
  • 提前包装 Bean
  • 为某些注解提供扩展支持

6. 初始化

Spring 会执行 Bean 的初始化逻辑,常见顺序一般包括:

(1)@PostConstruct

这是 JSR 规范提供的初始化注解。

(2)InitializingBean.afterPropertiesSet()

如果 Bean 实现了 InitializingBean 接口,Spring 会调用这个方法。

(3)自定义 init-method

如果在配置中指定了初始化方法,也会执行。

这一阶段通常用于:

  • 参数校验
  • 资源初始化
  • 建立连接
  • 预加载数据

7. BeanPostProcessor 后置处理

初始化完成后,Spring 会调用:

postProcessAfterInitialization()

这是生命周期中非常关键的一步,因为很多框架功能都在这里实现,例如:

  • AOP 代理对象的生成
  • @Transactional 的代理增强
  • 某些自动代理器的生效

也就是说,一个 Bean 在这一阶段可能会从原始对象变成代理对象


8. Bean 进入就绪状态

走完前面的流程后,Bean 才算真正初始化完成,变成一个可被应用程序正常使用的 Bean。

如果是单例 Bean,Spring 会把它放到单例池中缓存起来,后续直接从缓存获取。


9. Bean 的使用阶段

Bean 初始化完成后,就进入正常使用阶段。
在整个应用运行期间,业务代码通过 Spring 容器拿到 Bean 并调用它的方法。


10. Bean 销毁

当容器关闭时,Spring 会对 Bean 执行销毁逻辑。

常见销毁方式:

(1)@PreDestroy

(2)DisposableBean.destroy()

(3)自定义 destroy-method`

销毁阶段一般用于:

  • 关闭连接
  • 释放线程池
  • 清理缓存
  • 释放文件句柄等资源

三、Bean 生命周期的完整顺序总结

面试时可以按下面这个顺序回答:

  1. Spring 启动时先读取配置,解析生成 BeanDefinition
  2. 根据 BeanDefinition 实例化 Bean
  3. 对 Bean 进行属性填充,完成依赖注入
  4. 执行 Aware 接口回调
  5. 执行 BeanPostProcessor 的前置处理
  6. 执行初始化方法,包括 @PostConstructafterPropertiesSet()、自定义 init-method
  7. 执行 BeanPostProcessor 的后置处理
  8. Bean 初始化完成,进入单例池或可使用状态
  9. 容器关闭时,执行销毁方法,包括 @PreDestroydestroy()、自定义 destroy-method

四、为什么 BeanPostProcessor 很重要

BeanPostProcessor 是 Spring 生命周期扩展中最核心的接口之一。
因为 Spring 很多高级功能都不是直接写死在 Bean 生命周期里的,而是通过后置处理器扩展出来的。

例如:

  • AOP
  • 事务
  • 自动注入的一些增强能力
  • 各种注解驱动功能

尤其是 AOP 代理对象的创建,通常就发生在 postProcessAfterInitialization() 阶段。
所以可以说:

BeanPostProcessor 是 Spring 扩展机制的关键入口。


五、Bean 生命周期与作用域的关系

1. singleton

单例 Bean 由容器完整管理生命周期:

  • 创建
  • 初始化
  • 缓存
  • 销毁

2. prototype

原型 Bean 每次获取都会创建新对象。
Spring 只负责:

  • 创建
  • 依赖注入
  • 初始化

不会负责销毁
也就是说,prototype Bean 的销毁通常需要业务代码自己处理。

这是面试中很容易被问到的点。


六、总结

Spring Bean 生命周期可以概括为:Spring 启动后先读取配置并解析成 BeanDefinition,然后根据定义实例化 Bean,接着完成属性注入和依赖注入;之后执行 Aware 接口回调,再执行 BeanPostProcessor 前置处理、初始化方法以及 BeanPostProcessor 后置处理。初始化完成后,Bean 进入可用状态,如果是单例会被放入单例池。容器关闭时,Spring 会执行 Bean 的销毁逻辑。整个过程中,BeanPostProcessor 是非常关键的扩展点,AOP 和事务等功能通常都基于它实现。