AsyncConfigurerSupport自定義異步線程池處理異常
一、AsyncConfigurerSupport 簡介
spring 中開啟異步只要在配置類加上
@EnableAsync 同時在service方法中加上@Async即可,注意service中的方法想要異步調(diào)用必須是通過注入調(diào)用(spring 代理)。
@Service
public class ServiceA{
public void testA(){
testB();
}
@Async
public void testB(){
}
}
上述方法在調(diào)用testA時是同步調(diào)用,而非異步調(diào)用,方法內(nèi)部的直接調(diào)用是沒有經(jīng)過spring 代理的。
二、自定義異步調(diào)用的線程池和異常處理
AsyncConfigurerSupport 只定義了兩個方法分別用于自定義異步線程池、異步產(chǎn)生的異常捕獲,通過實現(xiàn)此類即可實現(xiàn)自定義的異步線程池。
demo如下:
新建子類 AsyncConfigHandler
@Configuration
@EnableAsync
public class AsyncConfigHandler extends AsyncConfigurerSupport {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(10);
executor.initialize();
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new MyAsyncUncaughtExceptionHandler();
}
@Bean // /actuator/shutdown
@Override
public Executor getAsyncExecutor2() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setTaskDecorator(new SomeTaskDecorator());
executor.setCorePoolSize(4);
executor.setMaxPoolSize(8);
executor.setQueueCapacity(100);
executor.setAllowCoreThreadTimeOut(false);
executor.setKeepAliveSeconds(0);
executor.setThreadNamePrefix("DefaultAsync-");
executor.setWaitForTasksToCompleteOnShutdown(true); // ? ????? ??
executor.initialize();
return executor;
}
static class SomeTaskDecorator implements TaskDecorator {
@Override
public Runnable decorate(Runnable runnable) {
return () -> {
try {
log.info("Some Task Decorator Start");
runnable.run();
} finally {
log.info("Some Task Decorator End");
}
};
}
}
}
class MyAsyncUncaughtExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable ex, Method method, Object... params) {
System.out.println("class#method: " + method.getDeclaringClass().getName() + "#" + method.getName());
System.out.println("type : " + ex.getClass().getName());
System.out.println("exception : " + ex.getMessage());
}
}編寫支持異步調(diào)用注解@Async的 DemoService
@Service
public class DemoService {
@Async
public void testAsync() throws InterruptedException {
System.out.println("這里是異步方法");
TimeUnit.SECONDS.sleep(10);
int i = 1 / 0;
}
}
編寫測試 controller
@RestController
@RequestMapping(value = "time")
public class DemoController {
@Autowired
private DemoService demoService;
@RequestMapping(value = "getTimeAndAsync")
public String getTimeAndAsync() throws InterruptedException {
demoService.testAsync();
return "異步加載=》" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
}
}新建spring boot應用的步驟省略
訪問 http://localhost:8080/time/getTimeAndAsync
瀏覽器會立即輸出
異步加載=》2021-02-20 15:56:16
等待十秒鐘后會捕獲異常
class#method: com.example.bootdemo.service.DemoService#testAsync
type : java.lang.ArithmeticException
exception : / by zero
同步調(diào)用中可以采用 @RestControllerAdvice 和 @ExceptionHandler 注解捕獲全局的異常然后進行處理,如果是異步調(diào)用則需要實現(xiàn) AsyncUncaughtExceptionHandler 進行單獨的額外處理。
以上就是AsyncConfigurerSupport自定義異步線程池實現(xiàn)的詳細內(nèi)容,更多關于AsyncConfigurerSupport異步線程池的資料請關注腳本之家其它相關文章!
相關文章
Struts2實現(xiàn)對action請求對象的攔截操作方法
這篇文章主要介紹了Struts2實現(xiàn)對action請求對象的攔截操作方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-11-11
Springboot應用中線程池配置詳細教程(最新2021版)
這篇文章主要介紹了Springboot應用中線程池配置教程(2021版),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03

