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

Spring 中的 destroy-method 是用来声明 Bean 销毁前要执行的清理方法,但它的生效有明确前提:只对 单例(singleton)Bean 有效,且容器必须被显式关闭(如调用 context.close() 或 context.registerShutdownHook()),否则不会触发。
destroy-method 的配置方式
支持两种主流配置形式,语义一致、效果相同:
-
XML 配置:在
<bean></bean>标签中直接指定方法名
-
Java 配置(@Bean):通过
destroyMethod属性传入方法名字符串
@Bean(destroyMethod = "shutdown")
public ScheduledExecutorService taskScheduler() {
return Executors.newScheduledThreadPool(4);
}
销毁方法本身的要求
被指定的方法需满足以下条件,Spring 才能成功调用:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 必须是 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()方法名,便于识别和维护
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










