实现了 AutoCloseable 接口,Spring 的底层机制会自动识别它,并将其注册为可销毁的 Bean。
为了让你更清楚地了解这个机制,我为你整理了详细的触发条件和执行原理:
1. 自动清理的触发条件
Spring 能够自动调用 close() 方法,需要满足以下两个核心条件:
- 必须是 Spring 管理的 Bean :你的
XskyFileStorageService需要被 Spring 容器管理(例如使用了@Component、@Service注解,或者在配置类中通过@Bean定义)。 - 必须是单例(Singleton) :这是最关键的一点。Spring 只会 自动管理单例 Bean 的销毁。
- 如果你的 Bean 是默认的单例模式(Spring 默认作用域),容器关闭时会调用
close()。 - 如果你的 Bean 是原型模式(Prototype) (即每次获取都创建新实例),Spring 容器不会 自动调用
close(),你需要自己手动调用或者使用 Bean 销毁回调接口。
- 如果你的 Bean 是默认的单例模式(Spring 默认作用域),容器关闭时会调用
2. 底层原理:适配器模式
Spring 之所以能识别 AutoCloseable,是因为在 Bean 生命周期的最后阶段(初始化后),Spring 会检查 Bean 的类型。
当 Spring 发现一个 Bean 实现了 AutoCloseable 接口时,它会使用一个内部类 DisposableBeanAdapter 将这个 Bean 包装起来。这个适配器实现了 Spring 标准的 DisposableBean 接口。
当容器关闭时,Spring 统一调用 DisposableBean.destroy() 方法,而这个适配器内部会将调用转发给你的 close() 方法。
3. 销毁方法的执行顺序
如果你在同一个 Bean 中同时使用了多种销毁方式,Spring 会按照特定的顺序执行。了解这个顺序对于排查问题很有帮助:
表格
| 执行顺序 | 销毁方式 | 说明 |
|---|---|---|
| 1 | @PreDestroy 注解 |
优先执行 JSR-250 标准的注解方法 |
| 2 | DisposableBean.destroy() |
接着执行 Spring 扩展接口的实现 |
| 3 | AutoCloseable.close() |
这就是你当前使用的方式 |
| 4 | 自定义 destroy-method |
最后执行配置中指定的销毁方法(如 XML 或 @Bean(destroyMethod=...)) |