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 接口回调@Overridepublic void setBeanName(String beanName) {System.out.println("3.1 BeanNameAware: beanName = " + beanName);}// 3.2 BeanFactoryAware 接口回调@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {System.out.println("3.2 BeanFactoryAware: beanFactory = " + beanFactory);}// 5.1 @PostConstruct 注解(需启用注解驱动)@PostConstructpublic void postConstruct() {System.out.println("5.1 @PostConstruct 方法调用");}// 5.2 InitializingBean 接口方法@Overridepublic 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 注解(需启用注解驱动)@PreDestroypublic void preDestroy() {System.out.println("8.1 @PreDestroy 方法调用");}// 8.2 DisposableBean 接口方法@Overridepublic 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. 初始化前处理@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) {if (bean instanceof DemoBean) {System.out.println("4. BeanPostProcessor.postProcessBeforeInitialization()");}return bean;}// 6. 初始化后处理@Overridepublic 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;}@Beanpublic 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()
)触发销毁方法。