ThreadPoolTask​​Executor 一直运行,如何控制关机?

gan*_*404 5 java executorservice application-shutdown threadpoolexecutor spring-boot

我正在使用 ThreadPoolTask​​Executor 编写 Spring Boot 应用程序。这是我的应用程序类:

import info.gandraweb.apns.service.MessageService;
import info.gandraweb.apns.settings.AppSettings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;

@SpringBootApplication
@EnableScheduling
@EnableAutoConfiguration
@EnableAsync
public class Application implements AsyncConfigurer{


    private static final Logger logger = LoggerFactory.getLogger(Application.class);


    @Autowired
    private AppSettings appSettings;

    public static void main(String[] args) {
        ApplicationContext applicationContext = SpringApplication.run(Application.class, args);
        AppSettings appSettings = applicationContext.getBean(AppSettings.class);
        logger.info(appSettings.toString());

        test(applicationContext);
    }

    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setThreadNamePrefix("MyExecutor-");
        taskExecutor.setCorePoolSize(10);
        taskExecutor.setMaxPoolSize(50);
        taskExecutor.setQueueCapacity(1000);
        taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        taskExecutor.initialize();
        return taskExecutor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new SimpleAsyncUncaughtExceptionHandler();
    }


    private static void test(ApplicationContext applicationContext) {
        MessageService messageService = applicationContext.getBean(MessageService.class);
        messageService.processNewMessages();
    }

}**
Run Code Online (Sandbox Code Playgroud)

我正在调用的内部测试方法

messageService.processNewMessages()

反过来,如果 DB 中存在某个任务,则调用另一个 bean 上的异步方法来处理它。当没有处理应用程序的任务完成时。
如果在执行后数据库中有任何任务需要处理,应用程序继续运行并且永远不会完成......似乎从未调用过 ThreadPoolTask​​Executor 上的 shutdown() 方法?

然后我实现了 ApplicationListener 接口并记录了 onApplicationEvent(ContextClosedEvent) 内部发生的事情

因此,当没有处理应用程序完成的任务并触发 ContextClosedEvent 时。执行后如果DB中有任务要处理不触发ContextClosedEvent???

当我从应用程序中删除 AsyncConfigurer 时,将触发 ContextClosedEvent 并关闭应用程序。但在这种情况下,我失去了配置 ThreadPoolTask​​Executor 的可能性。

那么,我如何配置 ThreadPoolTask​​Executor 并设法优雅地关闭这个执行器,或者触发 ContextClosedEvent ......无论是优雅地关闭它的首选方式是什么?