在 Spring Web 应用程序中,我有几个 DAO 和服务层 bean。一个服务层 bean 具有带注释的 @Async / @Scheduled 方法。这些方法依赖于其他(自动装配的)bean。
我在 XML 中配置了两个线程池:
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="2" />
<property name="maxPoolSize" value="5" />
<property name="queueCapacity" value="5" />
<property name="waitForTasksToCompleteOnShutdown" value="true" />
<property name="rejectedExecutionHandler">
<bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy"/>
</property>
</bean>
<bean id="taskScheduler" class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler">
<property name="poolSize" value="10" />
<property name="waitForTasksToCompleteOnShutdown" value="true" />
<property name="rejectedExecutionHandler">
<bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy"/>
</property>
</bean>
<task:annotation-driven executor="taskExecutor" scheduler="taskScheduler"/>
一切都按预期进行。我的问题是我无法彻底关闭任务池。这些任务在数据库和文件系统上运行。当我停止 Web 应用程序时,需要一些时间才能停止。这表明waitForTasksToCompleteOnShutdown
物业工程。但是,我在日志中收到 IllegalStateExceptions,表明某些 bean 已被破坏,但某些工作任务线程仍在执行,并且它们失败,因为它们的依赖项被破坏。
有一个可能相关的 JIRA 问题:SPR-5387 https://jira.springsource.org/browse/SPR-5387
我的问题是:有没有办法告诉Spring最后初始化任务执行器/调度程序bean,或者有没有办法告诉Spring首先销毁它们?
我的理解是破坏是以相反的初始化顺序发生的。因此最后初始化的 bean 将首先被销毁。如果线程池 bean 首先被销毁,则所有当前正在执行的任务都将完成,并且仍然可以访问依赖的 bean。
我还尝试使用线程池上的 dependent-on 属性来引用我的服务 bean,该服务 bean 具有 @Async 和 @Scheduled 注释。似乎它们永远不会被执行,并且我没有收到上下文初始化错误。我假设带注释的服务 bean 需要首先初始化这些线程池,如果我使用依赖项,我会颠倒顺序并使它们不起作用。
两种方式:
有一个豆工具ApplicationListener<ContextClosedEvent>
. onApplicationEvent()
将在上下文之前被调用并且所有 bean 都被销毁。
有一个豆工具生命周期 http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/context/Lifecycle.html or 智能生命周期 http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/context/SmartLifecycle.html. stop()
将在上下文之前被调用并且所有 bean 都被销毁。
无论哪种方式,您都可以在 Bean 销毁机制发生之前关闭任务内容。
Eg:
@Component
public class ContextClosedHandler implements ApplicationListener<ContextClosedEvent> {
@Autowired ThreadPoolTaskExecutor executor;
@Autowired ThreadPoolTaskScheduler scheduler;
@Override
public void onApplicationEvent(ContextClosedEvent event) {
scheduler.shutdown();
executor.shutdown();
}
}
(编辑:固定方法签名)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)