在 Tomcat 关闭时关闭 Spring 启动中的执行器服务

Shutdown of Executor service in Spring Boot when Tomcat shuts down

我在Spring Boot中配置了一个executor服务如下:

@Configuration
@PropertySource({ "classpath:executor.properties" })
public class ExecutorServiceConfig {

    @Value("${"executor.thread.count"}")
    private int executorThreadCount;

    @Bean("executorThreadPool")
    public ThreadPoolExecutor cachedThreadPool() {
        return new ThreadPoolExecutor(executorThreadCount, executorThreadCount, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
    }
}

该应用程序部署在一个独立的 Tomcat 实例上。当 Tomcat 服务器关闭时,我发现队列中还有未完成的任务。结果,我将丢失数据。我有没有办法在此执行程序服务上调用 awaitTermination,以便它有机会完成队列中的内容?谢谢!

@PreDestroy注释进行注释。然后从那里关闭 executo 服务。

@Configuration
class ExecutorServiceConfiguration {

    @Value("${"executor.thread.count"}")
    private int executorThreadCount;


     public static class MyExecutorService {
           private ThreadPoolExecutor executor;

           public MyExecutorService(ThreadPoolExecutor executor) {
               this.executor = executor;
           }
           @PreDestroy()
           public destroy() {
                  // destroy executor
           }
     }

    @Bean("executorThreadPool")
    public ThreadPoolExecutor cachedThreadPool() {
        return new ThreadPoolExecutor(executorThreadCount, executorThreadCount, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
    }

    @Bean
    public MyExecutorService configureDestroyableBean(ThreadPoolExecutor cachedThreadPool) 
    {
      return new MyExecutorService(cachedThreadPool);
    }

}

您可以通过根据需要配置 TomcatEmbeddedServletContainerFactory bean. It has a method addContextLifecycleListeners which allows you to instantiate your own LifecycleListener and handle any Tomcat Lifecycle Events 来连接到 Tomcat 生命周期(例如,通过在 ExecutorService 上调用 awaitTermination)。

@Configuration
public class TomcatConfiguration implements LifecycleListener {

    @Autowire("executorThreadPool")
    private ThreadPoolExecutor executor;

    @Bean
    public EmbeddedServletContainerFactory embeddedTomcatFactory() {
        TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
        factory.addContextLifecycleListeners(this);
        return factory;
    }

    @Override
    public void lifecycleEvent(LifeCycleEvent event) {
        //if check for correct event        
        executor.awaitTermination();
    }
}