美文网首页java高级开发spring frameworkjs css html
AsyncConfigurerSupport 自定义异步线程池

AsyncConfigurerSupport 自定义异步线程池

作者: 老鼠AI大米_Java全栈 | 来源:发表于2022-07-26 21:15 被阅读0次

    一、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 自定义异步线程池

        本文链接:https://www.haomeiwen.com/subject/ngqairtx.html