对于普通的Java对象来说,它们的生命周期就是:
- 实例化
- 对象不再被使用时通过垃圾回收机制进行回收
而对于Spring Bean的生命周期来说,可以分为四个阶段,其中初始化完成之后,就代表这个Bean可以使用了:
- 实例化
- 属性赋值
- 初始化
- 销毁
一、详细步骤
1、实例化
实例化阶段通过反射机制创建一个 Bean。
2、属性赋值
实例化完成后,Spring 会进行依赖注入,包括将属性值注入到 Bean 的字段中。
3、初始化
3.1 初始化前的扩展机制
- 执行 BeanNameAware#setBeanName、BeanFactoryAware#setBeanFactory 等 Aware 方法。
- 执行 BeanPostProcessor#postProcessBeforeInitialization() 方法。
3.2 初始化
- 执行被 @PostConstruct 注解的方法
- 执行 InitializingBean#afterPropertiesSet 方法。
- 执行 init-Method 方法。
3.3 初始化后的扩展机制
- 执行 BeanPostProcessor#postProcessAfterInitialization 方法。
4、销毁
- 执行 @PreDestroy 注解的方法
- 执行 DisposableBean#destroy 方法。
- 执行 destroy-method 方法。
二、实现方式
0、实例化之前
在 Bean 实例化之前,还可以通过 BeanFactoryPostProcessor 修改 Bean 的定义信息(如属性值)。
1、实例化
- 通过 Spring 的注解,如 @Bean、@Component 等。
- 通过配置文件。
2、属性赋值
- 通过注解,如 @Value 等。
- 通过构造函数、set 方法。
3、初始化(initMethod 的实现)
- 在 @Bean 注解里定义 initMethod。
@Bean(initMethod = "customInit") public LifecycleDemoBean lifecycleDemoBean() { return new LifecycleDemoBean(); }
- 在 xml 文件里定义 init-method。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean name="myBeanPostProcessor" class="com.jr.MyBeanPostProcessor" /> <bean name="personBean" class="com.jr.PersonBean" init-method="init" destroy-method="destroyMethod"> </bean> </beans>
4、销毁(destroy 方法的实现)
- 通过 @Bean 注解的 destroyMethod 属性指定一个销毁方法。
@Bean(destroyMethod = "customDestroy") public LifecycleDemoBean lifecycleDemoBean() { return new LifecycleDemoBean(); }
- 通过 xml 文件定义 destroy-method。
三、其他
1、Bean 的作用域(Scope)和生命周期的关系
- Singleton(单例):默认作用域,与 Spring 容器的生命周期一致。Bean 在容器启动时创建,关闭时销毁。
- Prototype(原型):每次请求创建一个新的 Bean 实例,容器只负责创建,不管理其生命周期。(通过 JVM 进行垃圾回收,如果需要执行特定的清理逻辑,需要在代码中显式地调用这些逻辑,或者实现DisposableBean接口和@PreDestroy注解来确保清理逻辑被执行。)
- Request、Session、Application、WebSocket:用于 Web 应用中,分别与 HTTP 请求,会话、应用或 WebSocket 的声明周期一致。
2、常见的生命周期应用场景
- 连接池管理:初始化阶段创建数据库连接池,销毁阶段关闭连接池,确保资源的有效管理。
- 缓存初始化:在 afterPropertiesSet 或 @PostConstruct 中加载缓存数据,在销毁阶段清理缓存。
- 动态代理创建:在 postProcessBeforeInitialization 中为 Bean 创建动态代理,以实现 AOP 功能。