Gio*_*tta 10 java junit spring multithreading executorservice
我有一个命令行应用程序,它使用由以下ExecutorService创建的java组成的Spring管理的bean :
ExecutorService service = Executors.newFixedThreadPool(4);
现在,我希望我的服务在我的应用程序关闭时关闭,所以我让我的bean实现了DisposableBean接口并且有一个destroy方法,例如:
public void destroy(){
  service.shutdown();
}
然后我可能想做一些事情,比如在Spring上下文中注册一个关闭钩子.然而,我发现(艰难的方式,即在预生产版本中)这不起作用:在调用ExecutorService.shutdown()方法之前不会调用shutdown钩子,导致经典的catch 22问题(它会被调用中断,即,如果我在应用程序运行时按Ctrl-C).这逃过了我的单元测试,因为出于某种原因,它似乎在JUnit中工作正常,这仍然令我感到困惑:JUnit的做法有何不同?
到目前为止我找到的解决方案是ApplicationContext.close()在退出main函数之前显式调用.我想知道是否有更好的解决方案,以及有什么是Spring管理的灵活线程池的最佳实践.如果我的bean 不是由Spring直接管理但是由Spring管理的bean创建的呢?我应该将调用级联到destroy()吗?这不是很容易出错吗?
我感谢任何评论,建议,进一步阅读,RTFM,魔术食谱.
谢谢!
Kei*_*ith 26
你知道吗:
ExecutorService service = Executors.newFixedThreadPool(4);
可以替换为:
<bean id="service" class="java.util.concurrent.Executors" 
      factory-method="newFixedThreadPool" destroy-method="shutdown">
    <constructor-arg value="4"/>
</bean>
然后,spring上下文更直接地管理执行程序服务的关闭 - 并且可以更容易地重用它.
根据官方 Spring 文档,当使用基于注解的配置时,对于destroyMethod字段@Bean,Spring 的默认行为是自动调用已命名的公共、无参数方法close或shutdown在关闭应用程序上下文时。
为方便用户,容器将尝试针对从@Bean 方法返回的对象推断销毁方法。例如,给定返回 Apache Commons DBCP BasicDataSource 的 @Bean 方法,容器将注意到该对象上可用的 close() 方法并自动将其注册为 destroyMethod。这种“破坏方法推断”目前仅限于检测名为“close”或“shutdown”的公共、无参数方法。该方法可以在继承层次结构的任何级别上声明,并且无论@Bean 方法的返回类型如何,都会被检测到(即,在创建时对 bean 实例本身进行反射检测)。
重申一下,当未明确设置 destroy 方法时,这是注释驱动配置的默认行为。如果不希望出现此行为,将 destroy 方法显式设置为空字符串将禁用此“功能”:
要禁用特定@Bean 的销毁方法推理,请指定一个空字符串作为值,例如@Bean(destroyMethod="")。请注意,仍然会检测到 DisposableBean 和 Closeable/AutoCloseable 接口并调用相应的 destroy/close 方法。
另一方面,当使用 XML 配置时,这不是默认行为......要实现奇偶校验,可以将destroy-method显式设置为(inferred)。有关详细信息,请参阅官方文档中的销毁回调和默认初始化和销毁方法部分。
| 归档时间: | 
 | 
| 查看次数: | 16735 次 | 
| 最近记录: |