destroy-method仅对单例Bean有效,需容器显式关闭才触发;支持XML的destroy-method属性和@Bean的destroyMethod参数两种配置,要求方法为public无参,可自定义名称。

Spring 中的 destroy-method 是用来声明 Bean 销毁前要执行的清理方法,但它的生效有明确前提:只对 单例(singleton)Bean 有效,且容器必须被显式关闭(如调用 context.close() 或 context.registerShutdownHook()),否则不会触发。
destroy-method 的配置方式
支持两种主流配置形式,语义一致、效果相同:
-
XML 配置:在
<bean>标签中直接指定方法名
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"
destroy-method="close">
<property name="jdbcUrl" value="jdbc:h2:mem:test"/>
</bean>
-
Java 配置(@Bean):通过
destroyMethod属性传入方法名字符串
@Bean(destroyMethod = "shutdown")
public ScheduledExecutorService taskScheduler() {
return Executors.newScheduledThreadPool(4);
}
立即学习“Java免费学习笔记(深入)”;
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
销毁方法本身的要求
被指定的方法需满足以下条件,Spring 才能成功调用:
- 必须是 public 方法(不能是 private/protected)
- 必须是 无参 方法(不接受任何参数)
- 返回类型任意(void 或其他均可,Spring 不关心返回值)
- 方法名可自定义(如
cleanup、release、shutDown),无需固定命名
示例:
public class FileWatcher {
private WatchService watchService;
public void start() throws IOException {
watchService = FileSystems.getDefault().newWatchService();
}
public void cleanup() { // ← 符合要求的销毁方法
if (watchService != null) {
try { watchService.close(); } catch (IOException ignored) {}
}
}
}
销毁时机与常见陷阱
容易忽略的关键点:
- prototype Bean 不走 destroy-method 流程:Spring 创建后即交由调用方管理,容器不负责其销毁
-
容器未正常关闭 = 不触发销毁:仅靠 JVM 退出或 Web 应用热部署,通常不会调用
close(),导致destroy-method永远不执行 -
多个销毁机制共存时有固定顺序:若同时使用
@PreDestroy、DisposableBean.destroy()和destroy-method,执行顺序为:@PreDestroy → destroy() → destroy-method - 异常会中断销毁链但不阻止后续 Bean 销毁:某个 Bean 的销毁方法抛出异常,不影响其他 Bean 的销毁回调执行
替代方案与推荐组合
对于新项目,建议优先使用标准注解 + 显式关闭保障:
- 用
@PreDestroy做常规资源释放(语义清晰、不耦合 Spring API) - 在启动类或配置类中注册
registerShutdownHook(),确保 JVM 关闭时容器自动 close - 对第三方库对象(如连接池、线程池),优先选用其自带的
close()/shutdown()方法名,便于识别和维护

















