我有一个命令行应用程序,它使用 Spring 管理的 bean,该 bean 由ExecutorService
创建的 java 组成:
ExecutorService service = Executors.newFixedThreadPool(4);
现在,我希望我的服务在我的应用程序关闭时关闭,所以我让我的 bean 实现了DisposableBean
接口并有一个销毁方法,例如:
public void destroy(){
service.shutdown();
}
然后我可能会想做一些事情,比如在 Spring 上下文中注册一个关闭钩子。但是我发现(困难的方式,即在预生产版本中)这不起作用:关闭钩子在调用ExecutorService.shutdown()
方法之前没有被调用,导致经典的 catch 22 问题(它确实被调用中断时,即,如果我在应用程序运行时按 Ctrl-C)。这逃脱了我的单元测试,因为出于某种原因,它似乎在 JUnit 中运行良好,这仍然让我感到困惑:JUnit 有什么不同?
到目前为止,我找到的解决方案是ApplicationContext.close()
在我退出主函数之前显式调用。我想知道是否有更好的解决方案,以及由 Spring 管理灵活线程池的最佳实践是什么。另外,如果我的 bean不是由 Spring 直接管理而是由 Spring 管理的 bean 创建的怎么办?我应该将调用级联到destroy()
吗?这不是很容易出错吗?
我感谢任何意见、建议、进一步阅读、RTFM、魔术食谱。
谢谢!