1.自定義TaskExecutor
(1)要想執行異步任務,還需要線程池,默認情況下Spring會在 ioc容器 中找唯一的org.springframework.core.task.TaskExecutor,或者一個 bean
name 為"taskExecutor" 的java.util.concurrent.Executor 作為執行任務的線程池。
(2) 如果都沒有的話,會創建 SimpleAsyncTaskExecutor 來處理異步方法調用.
此外如果 void 返回值的異步方法執行中出了異常,異常不會傳播到調用線程,默認情況下由SimpleAsyncUncaughtExceptionHandler 來處理,
只是簡單的紀錄了日志。
實現 AsyncConfigurer 來自定義 Executor 和異常處理:
/** * @author mafei007 * @date 2020/3/24 21:30 */ @Configuration @EnableAsync public class AppConfig implements AsyncConfigurer { @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(7); executor.setMaxPoolSize(42); executor.setQueueCapacity(11); executor.setThreadNamePrefix("MyExecutor-"); executor.initialize(); return executor; } @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return new CustomAsyncExceptionHandler(); } /** * 處理異步方法中未捕獲的異常 */ class CustomAsyncExceptionHandler implements AsyncUncaughtExceptionHandler { @Override public void handleUncaughtException(Throwable throwable, Method method, Object... obj) { System.out.println("Exception message - " + throwable.getMessage()); System.out.println("Method name - " + method.getName()); System.out.println("Parameter values - " + Arrays.toString(obj)); // do something... sendMailToAdmin(throwable.getMessage()); } } }
其它
@Async注解支持一個String參數,來指定一個bean name,類型是 Executor 或 TaskExecutor ,表示使用 ioc 容器中指定的線程池來執行這個異步任。
public class Task { @Async("Executor-001") public void task1(Long id) { // do something... } }