5

我正在用 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();
    }

}**

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

messageService.processNewMessages()

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

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

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

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

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

4

0 回答 0