当前位置: 首页 > 面试题库 >

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

姚向晨
2023-03-14
问题内容

在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

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

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

我还尝试在线程池上使用“依赖”属性,以引用具有@Async和@Scheduled批注的服务bean。好像它们从未执行过,并且我没有遇到上下文初始化错误。我假设带注释的服务bean某种程度上需要首先初始化这些线程池,如果我使用依赖,我会颠倒顺序并使它们不起作用。


问题答案:

两种方式:

  1. 有一个豆子工具ApplicationListener<ContextClosedEvent>onApplicationEvent()将在上下文和所有bean被销毁之前被调用。

  2. 有一个bean实现Lifecycle或SmartLifecycle。 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();
    }       
}

(编辑:固定方法签名)



 类似资料:
  • 问题内容: 在Spring Web应用程序中,我有几个DAO和服务层bean。一个服务层bean带有注释的@Async / @Scheduled方法。这些方法取决于其他(自动装配)的bean。我已经在XML中配置了两个线程池: 一切正常。我的问题是我无法完全关闭任务池才能正常工作。这些任务在数据库和文件系统上运行。当我停止Web应用程序时,它需要一些时间才能停止。这表明该waitForTasksT

  • 问题内容: 我需要能够动态加载/卸载角度应用程序而不会引起内存泄漏。在jQuery中,您可以执行相应的销毁代码,事件处理程序未绑定等。 我一直无法在有角度的文档中找到任何内容,提及启动应用程序后可能会拆除应用程序的可能性。 我的第一次尝试是像这样破坏rootScope: 但这似乎不起作用,而且我不确定即使清除了注入器和服务也将如何清理。 应该怎么做? 问题答案: 2013年3月10日更新: 我发现

  • 我有以下脚本,如果手动执行,它可以正常工作,但如果在任务计划程序中设置为任务,则不起作用,我怀疑这是一个未正确设置的参数,但我希望有人可以帮助我解决这个谜语 我强调了不工作的那一点,文件夹设置正确,但是java部分无法在任务调度器中执行,但是正如我所说的,手动是没问题的。谢谢你的时间

  • 我在Windows Server 2016上,尝试通过Windows任务调度器运行Java应用程序。我可以在cmd中执行Java应用程序。 这将执行程序并关闭java。exe之后。 如果我试着在任务调度器上运行它,它不会关闭java。exe之后。一段时间后,这会导致服务器上没有足够的内存来处理其预期用途。 我尝试将其直接添加到任务计划程序,并通过批处理,它不会在之后终止java.exe。 我的Ja

  • 我的问题是,在优雅地关闭应用程序之前,Spring会足够聪明地完成一个飞行中的任务吗?如果飞行中的任务在关机前完成,那么Spring会不会聪明到不启动另一个任务呢? 谢谢你。

  • 我是android studio的新手,正在制作一个简单的天气应用程序。我编写了代码,但仍然出现以下错误: 任务': app: dexDebug'执行失败。 通用域名格式。Android石斑鱼类。常见的过程ProcessException:org。格拉德尔。过程内部的ExecException:进程'command'/usr/lib/jvm/java-7-openjdk-amd64/bin/jav