AsyncConfigurerSupport自定义异步线程池处理异常
作者:老鼠AI大米_Java全栈
这篇文章主要为大家介绍了AsyncConfigurerSupport自定义异步线程池处理异常详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
一、AsyncConfigurerSupport 简介
spring 中开启异步只要在配置类加上
@EnableAsync 同时在service方法中加上@Async即可,注意service中的方法想要异步调用必须是通过注入调用(spring 代理)。
@Service public class ServiceA{ public void testA(){ testB(); } @Async public void testB(){ } }
上述方法在调用testA时是同步调用,而非异步调用,方法内部的直接调用是没有经过spring 代理的。
二、自定义异步调用的线程池和异常处理
AsyncConfigurerSupport 只定义了两个方法分别用于自定义异步线程池、异步产生的异常捕获,通过实现此类即可实现自定义的异步线程池。
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()); } }
编写支持异步调用注解@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
同步调用中可以采用 @RestControllerAdvice 和 @ExceptionHandler 注解捕获全局的异常然后进行处理,如果是异步调用则需要实现 AsyncUncaughtExceptionHandler 进行单独的额外处理。
以上就是AsyncConfigurerSupport自定义异步线程池实现的详细内容,更多关于AsyncConfigurerSupport异步线程池的资料请关注脚本之家其它相关文章!