Bean 生命周期是 Spring 容器的核心机制,从实例化 → 属性填充 → 初始化 → 使用 → 销毁,全程伴随扩展点供开发者介入。
一、完整生命周期流程图
┌─────────────────────────────────────────────────────────────────┐
│ Spring 容器启动 │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 1. 实例化(Instantiation) │
│ └─► 反射调用构造方法 newInstance() │
│ └─► 此时:对象已创建,属性均为 null │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 2. 属性填充(Populate) │
│ └─► 依赖注入 @Autowired / @Value / @Resource │
│ └─► 处理 @AutowiredAnnotationBeanPostProcessor │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 3. 初始化前(Post-process before initialization) │
│ └─► BeanPostProcessor.postProcessBeforeInitialization() │
│ └─► @PostConstruct 执行点(InitDestroyAnnotationProcessor) │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 4. 初始化(Initialization) │
│ └─► InitializingBean.afterPropertiesSet() │
│ └─► 自定义 init-method │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 5. 初始化后(Post-process after initialization) │
│ └─► BeanPostProcessor.postProcessAfterInitialization() │
│ └─► AOP 代理在此创建(AbstractAutoProxyCreator) │
│ └─► 返回的可能是 JDK 动态代理 / CGLIB 代理对象 │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 6. Bean 就绪,存入单例池(Singleton Pool) │
│ └─► DefaultSingletonBeanRegistry.singletonObjects │
│ └─► 供后续依赖注入使用 │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 7. 容器关闭(Destruction) │
│ └─► @PreDestroy 执行 │
│ └─► DisposableBean.destroy() │
│ └─► 自定义 destroy-method │
│ └─► 发布 ContextClosedEvent │
└─────────────────────────────────────────────────────────────────┘
二、核心扩展点详解
1. Aware 接口(获取容器资源)
@Component
public class MyBean implements
BeanNameAware, // 获取 beanName
BeanFactoryAware, // 获取 BeanFactory
ApplicationContextAware, // 获取 ApplicationContext
EnvironmentAware { // 获取 Environment
@Override
public void setBeanName(String name) {
System.out.println("① BeanNameAware: " + name);
}
@Override
public void setApplicationContext(ApplicationContext ctx) {
System.out.println("② ApplicationContextAware");
}
}
执行时机:属性填充之后,初始化之前。
2. BeanPostProcessor(全局拦截器)
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String name) {
// 初始化前:@PostConstruct 之前
if (bean instanceof MyService) {
System.out.println("Before init: " + name);
}
return bean; // 可返回代理对象替换原 bean
}
@Override
public Object postProcessAfterInitialization(Object bean, String name) {
// 初始化后:AOP 代理在此创建
if (bean instanceof MyService) {
// 创建代理,实现切面逻辑
return Proxy.newProxyInstance(...);
}
return bean;
}
}
经典应用:AOP、事务注解解析、@Async 代理创建。
3. 生命周期注解(JSR-250)
@Component
public class OrderService {
@PostConstruct
public void init() {
// 依赖注入完成后执行
// 用途:缓存预热、连接初始化、配置校验
System.out.println("③ @PostConstruct");
}
@PreDestroy
public void destroy() {
// 容器关闭前执行
// 用途:释放连接、保存状态、清理资源
System.out.println("⑦ @PreDestroy");
}
}
优先级:@PostConstruct > InitializingBean > init-method
4. InitializingBean / DisposableBean
@Component
public class PaymentService implements InitializingBean, DisposableBean {
@Override
public void afterPropertiesSet() throws Exception {
// 属性设置后,@PostConstruct 之后
System.out.println("④ InitializingBean");
}
@Override
public void destroy() throws Exception {
// 容器销毁时,@PreDestroy 之后
System.out.println("⑥ DisposableBean");
}
}
三、完整执行顺序验证
@Component
public class LifecycleDemo implements
BeanNameAware, InitializingBean, DisposableBean {
public LifecycleDemo() {
System.out.println("1. 构造方法(实例化)");
}
@Autowired
public void setDependency(Dependency dep) {
System.out.println("2. 依赖注入(属性填充)");
}
@Override
public void setBeanName(String name) {
System.out.println("3. BeanNameAware");
}
@PostConstruct
public void postConstruct() {
System.out.println("4. @PostConstruct");
}
@Override
public void afterPropertiesSet() {
System.out.println("5. InitializingBean");
}
public void customInit() {
System.out.println("6. init-method");
}
@PreDestroy
public void preDestroy() {
System.out.println("7. @PreDestroy");
}
@Override
public void destroy() {
System.out.println("8. DisposableBean");
}
public void customDestroy() {
System.out.println("9. destroy-method");
}
}
输出结果:
1. 构造方法(实例化)
2. 依赖注入(属性填充)
3. BeanNameAware
4. @PostConstruct
5. InitializingBean
6. init-method
[Bean 就绪,进入使用期]
7. @PreDestroy
8. DisposableBean
9. destroy-method
四、面试核心答法
"Bean 生命周期分五个阶段:实例化(构造方法)→ 属性填充(依赖注入)→ 初始化(Aware → @PostConstruct → InitializingBean → init-method → BeanPostProcessor 代理创建)→ 使用(单例池)→ 销毁(@PreDestroy → DisposableBean → destroy-method)。扩展点主要有 BeanPostProcessor(AOP 核心)、Aware 接口(获取容器资源)、生命周期注解。Spring 的 AOP 代理就是在初始化后的 postProcessAfterInitialization 中创建的。"
加分点:
- 提到 BeanPostProcessor 是 Spring AOP 的底层机制
- 说明 @PostConstruct 比 InitializingBean 更推荐(解耦 Spring 接口)
- 解释 为什么构造方法不能用 @Value(此时属性尚未注入)