Spring webapp – 在应用程序停止时关闭线程
我使用Spring的ApplicationListener接口实例化ScheduledExecutorService,如下所示:
@Component public class ExecutorsStart implements ApplicationListener { 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 { @Autowired ExecutorsStart executorsStart; @Override public void onApplicationEvent(final ContextStoppedEvent event) { executorsStart.executor.shutdownNow(); }
但是当Tomcat关闭时,似乎没有调用此事件处理程序。
我是否错误地实现了这个,或者我是否完全采用了这种方式?
您正在寻找ContextClosedEvent
。
@Component public class ExecutorsStop implements ApplicationListener { @Autowired ExecutorsStart executorsStart; @Override public void onApplicationEvent(final ContextClosedEvent event) { System.out.println("Stopped: " + event); } }
当Servlet容器关闭时,它在其各种ServletContextListener
上调用contextDestroyed(..)
并在其Servlet
实例上调用destroy()
。 ContextLoaderListener
和DispatcherServlet
分别在其ApplicationContext
上调用close()
。