ThreadPoolTaskExecutor でスプリング ブート アプリを作成しています。ここに私のアプリケーションクラスがあります:
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 メソッドを呼び出して処理します。処理アプリが終了するタスクがない場合。
実行後に処理するタスクがDBにある場合、アプリは実行を続けて終了しません.... ThreadPoolTaskExecutorのshutdown()メソッドが呼び出されないようです?
次に、 ApplicationListener インターフェイスを実装し、 onApplicationEvent(ContextClosedEvent) 内で何が起こっているかを記録しました
そのため、アプリの終了を処理するタスクがなく、ContextClosedEvent がトリガーされた場合。実行後に処理するタスクがDBにある場合、ContextClosedEventはトリガーされませんか???
アプリから AsyncConfigurer を削除すると、 ContextClosedEvent がトリガーされ、アプリがシャットダウンされます。しかし、そのような場合、ThreadPoolTaskExecutor を構成する可能性を失いました。
では、どのように ThreadPoolTaskExecutor を構成し、このエグゼキュータを正常にシャットダウンしたり、ContextClosedEvent をトリガーしたりできますか?