Appearance
Bean 生命周期
Spring Bean 的生命周期从"实例化"到"销毁",中间经过一系列扩展点,理解这些扩展点是掌握 Spring 的关键。
一、完整生命周期流程
Spring Bean 生命周期的 13 个阶段:
① 实例化(Instantiation)
通过构造器或工厂方法创建 Bean 实例
↓
② 属性填充(Populate Properties)
给 Bean 的属性赋值(@Autowired 注入、@Value 注入)
↓
③ BeanNameAware.setBeanName()
让 Bean 知道自己在容器中的名字
↓
④ BeanFactoryAware.setBeanFactory()
让 Bean 获取到 BeanFactory 引用
↓
⑤ ApplicationContextAware.setApplicationContext()
让 Bean 获取到 ApplicationContext 引用
↓
⑥ BeanPostProcessor.postProcessBeforeInitialization()
初始化前置处理(如 @PostConstruct 的处理者)
↓
⑦ @PostConstruct / InitializingBean.afterPropertiesSet()
Bean 自身的初始化逻辑
↓
⑧ init-method(XML)/ @Bean(initMethod = "init")
自定义初始化方法
↓
⑨ BeanPostProcessor.postProcessAfterInitialization()
初始化后置处理(AOP 代理对象的创建在这里)
↓
⑩ Bean 就绪,放入单例池,等待使用
... 容器关闭 ...
⑪ @PreDestroy
销毁前回调
↓
⑫ DisposableBean.destroy()
销毁回调
↓
⑬ destroy-method(XML)/ @Bean(destroyMethod = "destroy")
自定义销毁方法二、代码验证
java
@Component
public class MyBean implements BeanNameAware, BeanFactoryAware,
ApplicationContextAware, InitializingBean, DisposableBean {
// ① 构造器 → 实例化
public MyBean() {
System.out.println("① 构造器:实例化");
}
// ② 属性填充
@Autowired
private OtherBean otherBean;
// ③ BeanNameAware
@Override
public void setBeanName(String name) {
System.out.println("③ BeanNameAware: " + name);
}
// ④ BeanFactoryAware
@Override
public void setBeanFactory(BeanFactory beanFactory) {
System.out.println("④ BeanFactoryAware");
}
// ⑤ ApplicationContextAware
@Override
public void setApplicationContext(ApplicationContext ctx) {
System.out.println("⑤ ApplicationContextAware");
}
// ⑦ @PostConstruct
@PostConstruct
public void postConstruct() {
System.out.println("⑦ @PostConstruct");
}
// ⑦ InitializingBean
@Override
public void afterPropertiesSet() {
System.out.println("⑦ afterPropertiesSet");
}
// ⑧ 自定义 init
public void init() {
System.out.println("⑧ 自定义 init-method");
}
// ⑪ @PreDestroy
@PreDestroy
public void preDestroy() {
System.out.println("⑪ @PreDestroy");
}
// ⑫ DisposableBean
@Override
public void destroy() {
System.out.println("⑫ DisposableBean.destroy()");
}
}三、BeanPostProcessor 详解
BeanPostProcessor 是 Spring 最核心的扩展点之一,可以在 Bean 初始化前后插入自定义逻辑。
java
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
// ⑥ 在 @PostConstruct 之前执行
if (bean instanceof MyBean) {
System.out.println("⑥ BeanPostProcessor.before: " + beanName);
}
return bean; // 可以返回原对象或代理对象
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
// ⑨ 在 @PostConstruct 之后执行
if (bean instanceof MyBean) {
System.out.println("⑨ BeanPostProcessor.after: " + beanName);
}
return bean;
// AOP 就是在这里创建代理对象:
// return wrapIfNecessary(bean, beanName);
}
}四、Aware 接口族
Aware 接口让 Bean 能感知到 Spring 容器的上下文信息。
| 接口 | 作用 | 注入内容 |
|---|---|---|
| BeanNameAware | 获取 Bean 名称 | String beanName |
| BeanFactoryAware | 获取 BeanFactory | BeanFactory |
| ApplicationContextAware | 获取 ApplicationContext | ApplicationContext |
| EnvironmentAware | 获取 Environment | Environment |
| ResourceLoaderAware | 获取资源加载器 | ResourceLoader |
| ApplicationEventPublisherAware | 获取事件发布器 | ApplicationEventPublisher |
java
@Component
public class AwareBean implements ApplicationContextAware, EnvironmentAware {
private ApplicationContext ctx;
private Environment env;
@Override
public void setApplicationContext(ApplicationContext ctx) {
this.ctx = ctx;
}
@Override
public void setEnvironment(Environment env) {
this.env = env;
}
public void doSomething() {
String port = env.getProperty("server.port"); // 获取配置
ctx.publishEvent(new MyEvent(this)); // 发布事件
}
}五、面试要点
Q1:Bean 的生命周期有哪些阶段?
实例化 → 属性填充 → Aware 回调 → BeanPostProcessor.before → @PostConstruct → InitializingBean → init-method → BeanPostProcessor.after → 就绪 → 使用 → @PreDestroy → DisposableBean → destroy-method。
Q2:BeanPostProcessor 有什么用?
在 Bean 初始化前后插入自定义逻辑。AOP 代理对象的创建(postProcessAfterInitialization)、@PostConstruct 的处理(CommonAnnotationBeanPostProcessor)、@Autowired 的处理(AutowiredAnnotationBeanPostProcessor)都是通过 BeanPostProcessor 实现的。
Q3:@PostConstruct 和 InitializingBean 的 afterPropertiesSet 谁先执行?
@PostConstruct 先执行。因为 @PostConstruct 由 CommonAnnotationBeanPostProcessor 处理(在 BeanPostProcessor.before 阶段),afterPropertiesSet 是 InitializingBean 接口方法(在 afterPropertiesSet 阶段)。
