zoukankan      html  css  js  c++  java
  • Spring异步方法支持—@Async

      背景:前几周,公司的一个项目需要发送邮件,起初并没有考虑时间的影响,就未采用同步的方式进行发送。到了测试环境,发现需要发送邮件的地方耗时过久,因此研究了一下spring的异步方法支持—@Async,发现效果不错,在这里分享下。

      使用场景: 用于保证任务的及时性 ,适用于某一段耗时过长的代码,例如发送短信、邮件、调用第三方接口等等...  

    一、开启异步支持

      <!-- 异步任务线程池 -->

      <task:annotation-driven executor="asyncExecutor"/>
      <task:executor id="asyncExecutor" pool-size="5-20" queue-capacity="5"/>

      注意: @Async、@Transactional等注解采用的是代理模式,如果在同一个类的某个方法上,调用本类带有@Async等注解的方法是,该注解会失效。

    二、 @Async用法

    1. 注解应用范围:

      类: 如果该注解应用在类上,表示该类所有方法是异步的

      方法: 如果该注解应用在方法上,表示该方法是异步的

    2. 基于无返回值的调用 

    public void resetPassword() {
        System.out.println("#resetPassword() - reset password start...");
        smsHandler.send1();
        System.out.println("#resetPassword() - reset password end...");
    }
    
    @Async("asyncExecutor")
    public void send1() {
        Thread.sleep(5000);
        System.out.println("#notice1() - notice end...");
    }

    3. 基于@Async带返回值的调用

    public void resetPassword() {
        Future<String> future = smsHandler.send2();
        System.out.println(future.isDone());
    }
    
    @Async("asyncExecutor")
    public Future<String> send2() {
        Thread.sleep(5000);
        return new AsyncResult<String>("send success");
    }

    三、 @Async的异常处理

      如果是基于有返回值的调用,可通过Futrue进行异常的封装。如果是无返回值得调用,异常将无法被捕获和传递。Spring提供了AsyncUncaughtExceptionHandler接口进行该类问题的处理,默认的实现是 org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler, 我们可以也可以实现AsyncUncaughtExceptionHandler,实现自己项目需要的异常处理。

    1. 自定义异常处理类

    @Component("unbenAsyncUncaughtExceptionHandler")
    public class UnbenAsyncUncaughtExceptionHandler implements AsyncUncaughtExceptionHandler {
    
        private static final Logger logger = LoggerFactory.getLogger(UnbenAsyncUncaughtExceptionHandler.class);
        
        /* (non-Javadoc)
         * @see org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler#handleUncaughtException(java.lang.Throwable, java.lang.reflect.Method, java.lang.Object[])
         */
        public void handleUncaughtException(Throwable ex, Method method, Object... params) {
    
            logger.error("#handleUncaughtException() - exception=[{}], method=[{}], params=[{}]", 
                    ex.getMessage(), method.getDeclaringClass() + "#" + method.getName(), StringUtils.join(params, ", "));
            
        }
    
    }

    2. 配置

      <task:annotation-driven executor="asyncExecutor" exception-handler="unbenAsyncUncaughtExceptionHandler"/>

  • 相关阅读:
    vue_源码 原理 剖析
    vue_vuex
    vue_VueRouter 路由_路由器管理n个路由_并向路由组件传递数据_新标签路由_编程式路由导航
    vue_mint-ui
    vue_ajax 请求
    vue_组件间通信:自定义事件、消息发布与订阅、槽
    vue_小项目_吃饭睡觉打豆豆
    vue-cli 脚手架 Command Line Interface
    程序员面试金典-面试题 04.03. 特定深度节点链表
    程序员面试金典-面试题 04.02. 最小高度树
  • 原文地址:https://www.cnblogs.com/ark-blog/p/9028725.html
Copyright © 2011-2022 走看看