1. Bean 生命周期流程图
容器启动
│
├─1. Bean 实例化(调用构造函数)
│
├─2. 属性注入(依赖注入)
│
├─3. Aware 接口回调(BeanNameAware、BeanFactoryAware 等)
│
├─4. BeanPostProcessor.postProcessBeforeInitialization()
│
├─5. 初始化方法(@PostConstruct、InitializingBean.afterPropertiesSet()、init-method)
│
├─6. BeanPostProcessor.postProcessAfterInitialization()
│
├─7. Bean 就绪(进入可用状态)
│
└─容器关闭
│
├─8. 销毁方法(@PreDestroy、DisposableBean.destroy()、destroy-method)
│
└─资源释放
2. 核心阶段代码实现
示例 Bean 类
public class DemoBean implements BeanNameAware, BeanFactoryAware,
InitializingBean, DisposableBean {
private String name;
// 1. 实例化(构造函数)
public DemoBean() {
System.out.println("1. 构造函数调用");
}
// 2. 属性注入
public void setName(String name) {
this.name = name;
System.out.println("2. 属性注入: name = " + name);
}
// 3.1 BeanNameAware 接口回调
@Override
public void setBeanName(String beanName) {
System.out.println("3.1 BeanNameAware: beanName = " + beanName);
}
// 3.2 BeanFactoryAware 接口回调
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("3.2 BeanFactoryAware: beanFactory = " + beanFactory);
}
// 5.1 @PostConstruct 注解(需启用注解驱动)
@PostConstruct
public void postConstruct() {
System.out.println("5.1 @PostConstruct 方法调用");
}
// 5.2 InitializingBean 接口方法
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("5.2 InitializingBean.afterPropertiesSet()");
}
// 5.3 自定义初始化方法(XML/JavaConfig 配置)
public void customInit() {
System.out.println("5.3 自定义 init-method");
}
// 8.1 @PreDestroy 注解(需启用注解驱动)
@PreDestroy
public void preDestroy() {
System.out.println("8.1 @PreDestroy 方法调用");
}
// 8.2 DisposableBean 接口方法
@Override
public void destroy() throws Exception {
System.out.println("8.2 DisposableBean.destroy()");
}
// 8.3 自定义销毁方法(XML/JavaConfig 配置)
public void customDestroy() {
System.out.println("8.3 自定义 destroy-method");
}
}
BeanPostProcessor 实现
public class DemoBeanPostProcessor implements BeanPostProcessor {
// 4. 初始化前处理
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
if (bean instanceof DemoBean) {
System.out.println("4. BeanPostProcessor.postProcessBeforeInitialization()");
}
return bean;
}
// 6. 初始化后处理
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof DemoBean) {
System.out.println("6. BeanPostProcessor.postProcessAfterInitialization()");
}
return bean;
}
}
3. 配置方式
XML 配置
<bean id="demoBean" class="com.example.DemoBean"
init-method="customInit"
destroy-method="customDestroy">
<property name="name" value="test-bean"/>
</bean>
<bean class="com.example.DemoBeanPostProcessor"/>
Java 配置
@Configuration
public class AppConfig {
@Bean(initMethod = "customInit", destroyMethod = "customDestroy")
public DemoBean demoBean() {
DemoBean bean = new DemoBean();
bean.setName("test-bean");
return bean;
}
@Bean
public DemoBeanPostProcessor demoBeanPostProcessor() {
return new DemoBeanPostProcessor();
}
}
注解驱动支持
@Configuration
@ComponentScan(basePackages = "com.example")
@EnableAspectJAutoProxy // 启用注解驱动(如 @PostConstruct)
public class AppConfig {}
4. 测试代码
public class LifecycleTest {
public static void main(String[] args) {
// 创建容器
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
DemoBean bean = context.getBean(DemoBean.class);
System.out.println("7. Bean 已就绪: " + bean);
// 关闭容器(触发销毁方法)
context.close();
}
}
5. 输出结果
1. 构造函数调用
2. 属性注入: name = test-bean
3.1 BeanNameAware: beanName = demoBean
3.2 BeanFactoryAware: beanFactory = ...(容器对象)
4. BeanPostProcessor.postProcessBeforeInitialization()
5.1 @PostConstruct 方法调用
5.2 InitializingBean.afterPropertiesSet()
5.3 自定义 init-method
6. BeanPostProcessor.postProcessAfterInitialization()
7. Bean 已就绪: com.example.DemoBean@123456
8.1 @PreDestroy 方法调用
8.2 DisposableBean.destroy()
8.3 自定义 destroy-method
6. 关键扩展点总结
扩展方式 | 适用场景 | 优先级顺序 |
---|
@PostConstruct | 推荐使用,代码简洁 | 最先执行 |
InitializingBean | 框架接口,侵入性强 | 次之 |
init-method | XML/Java 配置,无侵入 | 最后执行 |
BeanPostProcessor | 全局拦截所有 Bean 的初始化过程 | 在初始化前后插入逻辑 |
7. 注意事项
- 作用域影响:
prototype
作用域的 Bean 不会触发销毁方法(需手动管理资源)。
- 执行顺序:
- Aware 接口回调在属性注入之后、初始化方法之前执行。
- 配置冲突:
- 若同时使用
@PostConstruct
、InitializingBean
和 init-method
,执行顺序如上所示。
- 容器关闭:
- 需调用
context.close()
(或 context.registerShutdownHook()
)触发销毁方法。