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...
}
}
