本文目录导读:

Spring Bean 的生命周期是指 Bean 从创建到销毁的全过程,这个过程由 Spring IoC 容器管理。
为了让你直观理解,可以把 Bean 生命周期抽象为四个主要阶段: 实例化 -> 属性赋值 -> 初始化 -> 销毁
下面我为你详细拆解这个过程,并重点说明“初始化”和“销毁”的多种实现方式。
Bean 生命周期流程图(核心)
graph TD
A[加载 Bean 定义] --> B(实例化 Bean)
B --> C{属性赋值 / DI}
C --> D[设置 Bean Name / BeanFactory 等 Aware 接口]
D --> E[BeanPostProcessor - postProcessBeforeInitialization]
E --> F{执行初始化}
F --> G[@PostConstruct]
G --> H[InitializingBean - afterPropertiesSet]
H --> I[自定义 init-method]
I --> J[BeanPostProcessor - postProcessAfterInitialization]
J --> K{Bean 准备就绪 / 使用}
K -- 容器关闭 --> L{执行销毁}
L --> M[@PreDestroy]
M --> N[DisposableBean - destroy]
N --> O[自定义 destroy-method]
O --> P[销毁完成]
详细阶段解析
实例化(Instantiation)
- 动作:通过反射调用构造器创建 Bean 的实例。
- 关键点:Bean 的属性都还是默认值(null 或 0)。
属性赋值(Populate Properties / Dependency Injection)
- 动作:Spring 自动注入 Bean 中声明了
@Autowired、@Value、@Resource等注解的属性,或者在 XML/Config 中配置的属性。 - 关键点:Bean 才真正拥有“数据”。
初始化前(Aware 接口回调)
- 动作:Bean 实现了某些 Aware 接口,Spring 会调用对应的 setter 方法,把容器相关信息注入给 Bean。
- 常见接口:
BeanNameAware:设置 Bean 在容器中的名称。BeanFactoryAware:设置 BeanFactory 容器。ApplicationContextAware:设置 ApplicationContext 上下文(常用,可用来获取其他 Bean)。
初始化前处理(BeanPostProcessor -> postProcessBeforeInitialization)
- 动作:Spring 内置或你自定义的
BeanPostProcessor的postProcessBeforeInitialization方法会被调用。 - 用途:这是一个全局拦截器,可以对所有 Bean 在初始化之前进行加工。
- 流行应用:
@Autowired注解的底层实现(AutowiredAnnotationBeanPostProcessor)就在这里工作。
初始化(Initialization)
这是开发者最常控制的阶段,有三种方式(按执行顺序):
| 顺序 | 方式 | 描述 | 特点 |
|---|---|---|---|
| 第一 | @PostConstruct 注解 |
在方法上加注解 | Java 标准注解(JSR-250),推荐使用 |
| 第二 | InitializingBean 接口 |
实现 afterPropertiesSet() 方法 |
Spring 专属接口,与 Spring 耦合 |
| 第三 | init-method 配置 |
在 @Bean(initMethod=“方法名”) 或 XML 中指定 |
适合在配置类中指定 |
注意:这三种方式可以共存,Spring 会严格按照上述顺序执行。
初始化后处理(BeanPostProcessor -> postProcessAfterInitialization)
- 动作:
BeanPostProcessor的postProcessAfterInitialization方法被调用。 - 用途:这是创建 Bean 代理对象的最佳时机。
- 流行应用:AOP(
AbstractAutoProxyCreator)在这里为 Bean 创建 JDK 动态代理或 CGLIB 代理。
Bean 就绪
- 经过以上步骤,Bean 被放入 Spring 容器的“单例池”(Singleton Objects)中,可以供其他代码使用了。
销毁(Destruction)
当容器关闭时(例如调用 context.close()),会按照逆序执行销毁逻辑,同样有三种方式:
| 顺序 | 方式 | 描述 | 特点 |
|---|---|---|---|
| 第一 | @PreDestroy 注解 |
在方法上加注解 | Java 标准注解(JSR-250),推荐使用 |
| 第二 | DisposableBean 接口 |
实现 destroy() 方法 |
Spring 专属接口,与 Spring 耦合 |
| 第三 | destroy-method 配置 |
在 @Bean(destroyMethod=“方法名”) 或 XML 中指定 |
适合在配置类中指定 |
实战代码示例
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class MyBean implements InitializingBean, DisposableBean,
BeanNameAware, ApplicationContextAware {
private String beanName;
private ApplicationContext applicationContext;
// 1. 构造器 (实例化)
public MyBean() {
System.out.println("1. 构造器: 实例化 Bean");
}
// 2. 属性赋值 (略,假设有 @Autowired)
// 3. Aware 接口回调
@Override
public void setBeanName(String name) {
this.beanName = name;
System.out.println("3. Aware: BeanNameAware -> " + name);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
System.out.println("3. Aware: ApplicationContextAware");
}
// 5. 初始化阶段
// 第一种方式:@PostConstruct (最推荐)
@PostConstruct
public void customInitAnnotation() {
System.out.println("5.1 初始化: @PostConstruct");
}
// 第二种方式:InitializingBean 接口
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("5.2 初始化: InitializingBean.afterPropertiesSet()");
}
// 第三种方式:init-method (假设在配置中指定了 @Bean(initMethod = "customInitMethod"))
// 如果配置了,会在此处执行,但为了简洁,这里不重复展示
// 8. 销毁阶段
// 第一种方式:@PreDestroy (最推荐)
@PreDestroy
public void customDestroyAnnotation() {
System.out.println("8.1 销毁: @PreDestroy");
}
// 第二种方式:DisposableBean 接口
@Override
public void destroy() throws Exception {
System.out.println("8.2 销毁: DisposableBean.destroy()");
}
// 第三种方式:destroy-method (类似 init-method)
/**
* 业务方法
*/
public void doSomething() {
System.out.println("7. Bean 就绪: 执行业务逻辑");
}
}
// 配置类 (需要开启注解扫描)
@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
// 如果使用 @Bean 方式,可以指定 initMethod 和 destroyMethod
@Bean(initMethod = "customInitMethod", destroyMethod = "customDestroyMethod")
public AnotherBean anotherBean() {
return new AnotherBean();
}
}
BeanPostProcessor 与 BeanFactoryPostProcessor 的区别
这是面试常考点,也是容易混淆的地方。
| 特性 | BeanPostProcessor |
BeanFactoryPostProcessor |
|---|---|---|
| 执行时机 | Bean 实例化之后,初始化前后执行 | Bean 实例化之前,Bean 定义加载之后执行 |
| 操作对象 | Bean 实例(可以修改Bean的属性或返回代理对象) | BeanDefinition(可以修改Bean的定义,如作用域、属性值) |
| 典型应用 | AOP、@Autowired、属性填充 |
PropertySourcesPlaceholderConfigurer(解析占位符) |
BeanPostProcessor:是用来“加工” Bean 对象的。BeanFactoryPostProcessor:是用来“修改” Bean 配置元数据的。
高频面试题
-
JSR250 规范的生命周期注解是什么?
@PostConstruct和@PreDestroy。
-
Spring 如何保证 Bean 初始化顺序?
- 实现
Ordered接口或使用@Order注解(主要针对集合注入、BeanPostProcessor排序)。 - 使用
@DependsOn注解强制指定依赖的 Bean 先初始化。
- 实现
-
BeanPostProcessor和Aware接口的执行顺序是怎样的?- 先执行
Aware接口回调(设置 Bean Name、Context)。 - 再执行
BeanPostProcessor.postProcessBeforeInitialization。 - 然后执行初始化方法(
@PostConstruct->InitializingBean->init-method)。 - 最后执行
BeanPostProcessor.postProcessAfterInitialization。
- 先执行
-
如果一个 Bean 在 DI 时发生循环依赖,Spring 如何处理?
- 三级缓存机制:Spring 通过提前暴露半成品 Bean(
ObjectFactory)来解决单例模式下 setter 注入的循环依赖。构造器注入的循环依赖无法解决,只能报错。
- 三级缓存机制:Spring 通过提前暴露半成品 Bean(
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播