Bean 生命周期不是一串需要背诵的接口,而是“对象从配方到可用实例,再到资源释放”的有序协议。自定义逻辑应放在职责匹配的扩展点。
Table of contents
Open Table of contents
运行生命周期记录器
LifecycleRecorder下载记录问候服务初始化前后、所有单例就绪和容器销毁:
mvn -Dtest=SpringSourceLabTest#recordsBeanLifecyclePhases test
测试显式关闭 Context,并验证销毁事件。只测启动不测关闭,会遗漏连接池、执行器和后台线程泄漏。
单个 Bean 的主线
实例化 -> 属性填充 -> Aware 回调 -> 初始化前处理
-> 初始化方法 -> 初始化后处理 -> 对外可用 -> 销毁
构造器执行属于实例化;依赖注入主要发生在属性填充和构造阶段。BeanNameAware 等 Aware 接口让对象获知容器信息,但业务对象滥用它们会增加框架耦合。
@PostConstruct、InitializingBean 和自定义 init 方法都用于初始化。优先使用不依赖 Spring 接口的方式,并保证初始化只做本地、有界工作;不要在启动中执行无截止时间的远程调用。
后置处理器可能返回另一个对象
BeanPostProcessor.postProcessAfterInitialization 可以返回代理而不是原实例。调用者从 Context 取得的是代理,构造器内部的 this 仍是目标对象。AOP 和声明式事务的自调用问题由此产生。
实现后置处理器时,只处理明确目标类型,并原样返回不相关 Bean。返回 null 或提前获取大量 Bean 都可能破坏后续链条。
销毁是生产能力
@PreDestroy、DisposableBean 或 destroy method 适合关闭执行器、客户端和文件句柄。销毁操作要幂等、有超时并保留失败日志。JVM 直接被杀死时回调无法保证执行,外部系统仍要依赖租约和超时恢复。
下一步
阅读构造器推断与依赖解析,理解容器如何在多个构造器和候选 Bean 之间做决定。