我正在使用 Spring 的 ApplicationListener 接口(interface)实例化一个 ScheduledExecutorService,如下所示:
@Component
public class ExecutorsStart implements ApplicationListener<ContextRefreshedEvent> {
private ScheduledExecutorService executor;
@Autowired
Scheduler scheduler;
@Override
public void onApplicationEvent(final ContextRefreshedEvent event) {
executor = Executors.newSingleThreadScheduledExecutor();
scheduler.init();
int delay = 10;
int period = 60;// repeat every 1 minutes.
executor.scheduleAtFixedRate(scheduler, delay, period, TimeUnit.SECONDS);
}
目前,当我运行 ./shutdown.sh 时,Tomcat 不会干净地关闭,并显示消息:
The web application [/foo] appears to have started a thread named [pool-1-thread-1] but has failed to stop it
这似乎是因为我还没有编写代码来停止 ScheduledExecutorService。
我的问题是:在这种环境下应该如何正确完成?
我注意到存在一个 ContextStoppedEvent ,所以,我为它实现了一个监听器:
@Component
public class ExecutorsStop implements ApplicationListener<ContextStoppedEvent> {
@Autowired
ExecutorsStart executorsStart;
@Override
public void onApplicationEvent(final ContextStoppedEvent event) {
executorsStart.executor.shutdownNow();
}
但似乎在 Tomcat 关闭时不会调用此事件处理程序。
我是否错误地实现了这一点,还是我完全按照 wong 的方式进行了?
最佳答案
您正在寻找 ContextClosedEvent
。
@Component
public class ExecutorsStop implements ApplicationListener<ContextClosedEvent> {
@Autowired
ExecutorsStart executorsStart;
@Override
public void onApplicationEvent(final ContextClosedEvent event) {
System.out.println("Stopped: " + event);
}
}
当 Servlet 容器关闭时,它会在其各种 ServletContextListener
上调用 contextDestroyed(..)
并在其 上调用
实例。 destroy()
>ServletContextLoaderListener
和 DispatcherServlet
分别调用 close()
在他们的 ApplicationContext
上。
关于java - Spring webapp - 在应用程序停止时关闭线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22650569/