1400 字
7 分钟
spring bean的生命周期
Spring Bean 的生命周期是指从 Bean 被创建、初始化、使用到最终销毁的完整过程。这个过程由 Spring IoC 容器全程管理,包含多个关键阶段,每个阶段都允许开发者通过特定机制(如接口、注解)介入并添加自定义逻辑。以下是 Spring Bean 完整生命周期的详细描述:
一、Bean 生命周期的核心阶段(11 个关键步骤)
1. 实例化(Instantiation)
- 作用:创建 Bean 的实例(内存分配),相当于调用类的构造函数。
- 细节:容器根据
BeanDefinition中的类信息(如class属性),通过反射创建对象。此时对象仅完成实例化,属性尚未设置,依赖也未注入。
2. 设置属性(Population)
- 作用:为实例化后的对象设置属性值和依赖的 Bean(依赖注入,DI)。
- 细节:
- 容器会解析 Bean 的属性信息(如
@Autowired、@Value注解或 XML 中的<property>配置)。 - 将对应的属性值(基本类型、字符串)或其他 Bean 的引用注入到当前对象中。
- 若属性是另一个 Bean,会先确保依赖的 Bean 已完成实例化(解决循环依赖问题)。
- 容器会解析 Bean 的属性信息(如
3. 检查 Aware 接口并设置相关依赖
-
作用:让 Bean 感知 Spring 容器的上下文信息。
-
细节:若 Bean 实现了以下Aware
接口,容器会调用对应的方法注入相关对象:
BeanNameAware:注入当前 Bean 的名称(setBeanName(String name))。BeanClassLoaderAware:注入类加载器(setBeanClassLoader(ClassLoader classLoader))。BeanFactoryAware:注入当前 Bean 所在的BeanFactory(setBeanFactory(BeanFactory beanFactory))。ApplicationContextAware(若容器是ApplicationContext):注入ApplicationContext(setApplicationContext(ApplicationContext applicationContext))。
4. BeanPostProcessor 前置处理(postProcessBeforeInitialization)
- 作用:在 Bean 初始化前执行自定义逻辑,可修改 Bean 实例。
- 细节:
- 容器会遍历所有注册的
BeanPostProcessor,依次调用其postProcessBeforeInitialization方法。 - 典型应用:Spring AOP 在此阶段为 Bean 创建代理对象(如
@Transactional注解的 Bean)。 - 方法返回值可为修改后的 Bean 实例(如代理对象),若返回
null则会忽略当前 Bean。
- 容器会遍历所有注册的
5. 初始化前(@PostConstruct)
- 作用:执行用户自定义的初始化前置逻辑(JSR-250 标准注解)。
- 细节:若 Bean 的方法标注了
@PostConstruct,容器会在初始化阶段前调用该方法(早于InitializingBean和自定义初始化方法)。
6. 执行 InitializingBean 接口的 afterPropertiesSet 方法
- 作用:Spring 提供的初始化回调接口。
- 细节:若 Bean 实现了
InitializingBean接口,容器会调用其afterPropertiesSet()方法,通常用于检查属性是否已正确设置(如 “必须设置数据库连接 URL”)。
7. 执行自定义初始化方法(init-method)
- 作用:执行用户通过配置指定的初始化方法。
- 细节:
- 可通过 XML 配置(
init-method="init")或注解(@Bean(initMethod = "init"))指定方法。 - 方法名自定义(如
init()、start()),用于完成 Bean 的初始化逻辑(如连接数据库、加载缓存)。
- 可通过 XML 配置(
8. BeanPostProcessor 后置处理(postProcessAfterInitialization)
- 作用:在 Bean 初始化后执行自定义逻辑,可对 Bean 进行最终修饰。
- 细节:
- 容器遍历所有
BeanPostProcessor,调用其postProcessAfterInitialization方法。 - 若前置处理阶段未创建代理,此阶段可能进一步处理(如 Spring 事务管理的代理增强)。
- 容器遍历所有
9. Bean 就绪(Ready for Use)
- 作用:Bean 已完成所有初始化,可被应用程序使用。
- 细节:
- 单例 Bean 会被缓存到容器中,供多次获取;原型 Bean 每次获取时都会重新创建生命周期。
- 应用程序通过
ApplicationContext.getBean()或依赖注入获取 Bean 并调用其方法。
10. 销毁前(@PreDestroy)
- 作用:执行用户自定义的销毁前置逻辑(JSR-250 标准注解)。
- 细节:若 Bean 的方法标注了
@PreDestroy,容器会在销毁前调用该方法(早于DisposableBean和自定义销毁方法)。
11. 执行 DisposableBean 接口的 destroy 方法
- 作用:Spring 提供的销毁回调接口。
- 细节:若 Bean 实现了
DisposableBean接口,容器会调用其destroy()方法,用于释放资源(如关闭数据库连接、清理缓存)。
12. 执行自定义销毁方法(destroy-method)
- 作用:执行用户通过配置指定的销毁方法。
- 细节:
- 可通过 XML 配置(
destroy-method="destroy")或注解(@Bean(destroyMethod = "destroy"))指定方法。 - 方法名自定义(如
destroy()、shutdown()),用于完成 Bean 的最终清理工作。
- 可通过 XML 配置(
二、关键扩展点(开发者可介入的机制)
BeanPostProcessor接口:最强大的扩展点,可在初始化前后拦截所有 Bean 的创建过程(如 AOP 代理、属性校验)。Aware接口族:让 Bean 主动获取容器信息(如名称、上下文),但需谨慎使用(增加与 Spring 的耦合)。- 初始化 / 销毁注解与接口:
@PostConstruct/@PreDestroy、InitializingBean/DisposableBean、自定义init-method/destroy-method,用于添加业务相关的初始化和清理逻辑。
三、单例与原型 Bean 的生命周期差异
- 单例 Bean:生命周期与容器一致,容器启动时创建(除非配置
lazy-init="true"),容器关闭时销毁。 - 原型 Bean:容器仅负责创建和初始化,之后不再管理其生命周期(不会调用销毁方法),需开发者手动管理。
总结
Spring Bean 的生命周期可概括为:实例化 → 属性注入 → 容器感知 → 前置处理 → 初始化(3 个阶段) → 后置处理 → 就绪使用 → 销毁(3 个阶段)。整个过程中,Spring 提供了丰富的扩展点,允许开发者在关键节点介入,这既保证了框架的灵活性,也让 Bean 的管理更加可控。理解 Bean 生命周期,有助于更好地设计和调试 Spring 应用(如解决初始化顺序问题、资源释放问题等)。
spring bean的生命周期
https://blog.sunycode.cn/posts/spring/spring-bean的生命周期/