gpt4 book ai didi

java - 如何在 Web 应用程序中的所有其他 bean 被销毁之前关闭 Spring 任务执行器/调度器池?

转载 作者:IT老高 更新时间:2023-10-28 13:04:07 27 4
gpt4 key购买 nike

在 Spring Web 应用程序中,我有几个 DAO 和服务层 bean。一个服务层 bean 已注释 @Async/@Scheduled 方法。这些方法依赖于其他( Autowiring 的)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

我的问题是:有没有办法告诉 Spring 最后初始化任务执行器/调度程序 bean,或者有没有办法告诉 Spring 先销毁它们?

我的理解是破坏以相反的初始化顺序发生。因此,最后初始化的 bean 将首先被销毁。如果线程池bean首先被销毁,所有当前正在执行的任务都会完成并且仍然可以访问依赖的bean。

我还尝试在引用我的服务 bean 的线程池上使用依赖属性,该服务 bean 具有 @Async 和 @Scheduled 注释。似乎它们从未执行过,并且我没有收到上下文初始化错误。我假设带注释的服务 bean 不知何故需要首先初始化这些线程池,如果我使用依赖,我会颠倒顺序并使它们不起作用。

最佳答案

两种方式:

  1. 有 bean 器ApplicationListener<ContextClosedEvent> . onApplicationEvent()将在上下文之前被调用并且所有 bean 都被销毁。

  2. 有 bean 器LifecycleSmartLifecycle . stop()将在上下文之前被调用并且所有 bean 都被销毁。

无论哪种方式,您都可以在 bean 销毁机制发生之前关闭任务。

例如:

@Component
public class ContextClosedHandler implements ApplicationListener<ContextClosedEvent> {
@Autowired ThreadPoolTaskExecutor executor;
@Autowired ThreadPoolTaskScheduler scheduler;

@Override
public void onApplicationEvent(ContextClosedEvent event) {
scheduler.shutdown();
executor.shutdown();
}
}

(编辑:固定方法签名)

关于java - 如何在 Web 应用程序中的所有其他 bean 被销毁之前关闭 Spring 任务执行器/调度器池?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6603051/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com