在深入理解Spring框架时,IoC容器的核心——Bean的生命周期管理是必须掌握的概念。整个流程细节繁多,难以完整记忆,但只需抓住几个关键扩展点即可满足大多数开发需求。从宏观视角看,Bean的生命周期如下图所示:

对于应用开发者而言,最主要的是利用Spring提供的两个业务扩展钩子,实现对Bean初始化和销毁过程的定制:
- 初始化扩展:在Bean属性设置完成后、投入使用前,执行自定义逻辑。
- 销毁扩展:在Bean被容器销毁之前,执行清理逻辑。
常见的应用场景包括:
- 初始化数据库连接、网络套接字、文件句柄等资源。
- 执行启动时的数据加载或缓存预热。
- 销毁前关闭资源、保存状态或发送通知。
1. 初始化钩子:@PostConstruct
只需在方法上添加 @PostConstruct 注解,该方法便会在Bean的初始化阶段被 Spring容器 自动调用。这是执行启动逻辑最便捷的方式。
@Component
public class CricketCoach implements Coach {
public CricketCoach() {
System.out.println("In constructor: " + getClass().getSimpleName());
}
@PostConstruct
public void doMyStartupStuff() {
System.out.println("In myInit method: " + getClass().getSimpleName());
// 此处可添加自定义初始化代码,如建立数据源连接
}
}
重启应用后,控制台将依次打印构造器和初始化方法的日志(请确保移除了之前可能设置的全局懒加载配置)。
2. 销毁钩子:@PreDestroy
同理,在方法上添加 @PreDestroy 注解,该方法会在Bean实例被容器销毁之前调用,适用于资源清理。
@Component
public class CricketCoach implements Coach {
public CricketCoach() {
System.out.println("In constructor: " + getClass().getSimpleName());
}
@PostConstruct
public void doMyStartupStuff() {
System.out.println("In myInit method: " + getClass().getSimpleName());
}
@PreDestroy
public void doMyCleanupStuff() {
System.out.println("In myDestroy method: " + getClass().getSimpleName());
// 此处可添加自定义清理代码,如关闭文件流、断开网络连接
}
}
当正常停止Spring Boot应用时,可以在控制台看到销毁方法的输出日志。
重要提示:关于 Prototype 作用域 Bean 的销毁
对于作用域为 prototype 的Bean,@PostConstruct 注解的初始化方法仍会生效,但 @PreDestroy 注解的销毁方法将不会被调用。
这是因为 核心IoC容器 对 prototype Bean的生命周期管理策略不同:容器负责实例化、配置和组装原型Bean,之后将其交给客户端,便不再跟踪和管理该实例的后续生命周期,因此不会触发预定义的销毁回调。这也体现了Spring在Bean生命周期管理上的灵活性。
通过这两个简单的注解,开发者可以轻松介入Spring Bean生命周期的关键节点,实现高效的 资源管理 和业务逻辑的初始化和清理,是构建健壮Java应用的基础技能。
|