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應(yīng)用的步驟省略
訪問 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 注解捕獲全局的異常然后進(jìn)行處理,如果是異步調(diào)用則需要實現(xiàn) AsyncUncaughtExceptionHandler 進(jìn)行單獨(dú)的額外處理。
以上就是AsyncConfigurerSupport自定義異步線程池實現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于AsyncConfigurerSupport異步線程池的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Struts2實現(xiàn)對action請求對象的攔截操作方法
這篇文章主要介紹了Struts2實現(xiàn)對action請求對象的攔截操作方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-11-11Springboot應(yīng)用中線程池配置詳細(xì)教程(最新2021版)
這篇文章主要介紹了Springboot應(yīng)用中線程池配置教程(2021版),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03