我有一个命令行应用程序,它使用一个Spring管理的bean,该bean由一个java ExecutorService
组成,该bean是用以下命令创建的:
ExecutorService service = Executors.newFixedThreadPool(4);
字符串
现在,我希望我的服务在我的应用程序关闭时关闭,所以我让我的bean实现了DisposableBean
接口,并有一个destroy方法,如:
public void destroy(){
service.shutdown();
}
型
然后我可能会尝试在Spring上下文中注册一个shutdown hook。(硬的方式,即在预生产版本),这不工作:在调用ExecutorService.shutdown()
方法之前,shutdown钩子不会被调用,这会导致经典的catch 22问题(它确实会在中断时被调用,也就是说,如果我在应用程序运行时按下Ctrl-C)。这逃过了我的单元测试,因为出于某种原因,它似乎在JUnit内部工作得很好,这仍然让我感到困惑:JUnit做什么有所不同?
到目前为止,我找到的解决方案是在退出main函数之前显式调用ApplicationContext.close()
。我想知道是否有更好的解决方案,以及由Spring管理灵活线程池的最佳实践是什么。还有,如果我的bean不是由Spring直接管理的,而是由Spring管理的bean创建的,那该怎么办?我应该级联调用destroy()
吗?这不是很容易出错吗?
我感谢任何意见,建议,进一步阅读,RTFM,神奇食谱。
谢谢你,谢谢
5条答案
按热度按时间5q4ezhmt1#
你是否意识到:
字符串
可以替换为:
型
然后spring上下文会更直接地管理executor服务的关闭--并且可以更容易地重用它。
bxfogqkk2#
根据官方Spring文档,当使用基于注解的配置时,对于
@Bean
的destroyMethod字段,Spring的默认行为是在应用程序上下文关闭时自动调用名为close
或shutdown
的公共无参数方法。为了方便用户,容器将尝试根据从@Bean方法返回的对象推断destroy方法。例如,给定返回Apache Commons DBCP BasicDataSource的@Bean方法,容器将注意到该对象上可用的close()方法并自动将其注册为destroyMethod。这种“destroy方法推断”目前仅限于检测public,名为'close'或'shutdown'的no-arg方法。该方法可以在继承层次结构的任何级别声明,并且无论@Bean方法的返回类型如何都将被检测到(即,在创建时对Bean示例本身进行反射检测)。
重新定义,这是 annotation-driven 配置在没有显式设置destroy方法时的默认行为。如果不需要此行为,显式设置destroy方法为空字符串将禁用此“功能”:
要禁用特定@Bean的destroy方法推断,请指定一个空字符串作为值,例如@Bean(destroyMethod="”)。请注意,DisposableBean和Closeable/AutoCloseable接口仍然会被检测到,并调用相应的destroy/close方法。
另一方面,当使用XML配置时,这不是默认行为.为了实现奇偶校验,destroy-method可以显式设置为
(inferred)
。有关详细信息,请参阅官方文档中的Destruction回调和默认初始化以及destroy方法部分。h22fl7wq3#
考虑使用Spring的TaskExecutor,它可以配置线程池。http://static.springsource.org/spring/docs/3.0.x/reference/scheduling.html
osh3o9ms4#
只是想将基于配置的ExecutorService bean创建添加到@基思的答案中
字符串
oyxsuwqo5#
也可以使用
@PreDestroy
注解:字符串
或者,如果
ExecutorService
本身是一个bean:型