Spring 异步执行之@Async揭秘

2021-03-13 13:33

阅读:501

标签:过程   sync   容器管理   基于   executor   java   and   aspectj   不用   

背景

在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的;但是在处理与第三方系统交互的时候,容易造成响应迟缓的情况,之前大部分都是使用多线程来完成此类任务,其实,在Spring 3.x之后,就已经内置了@Async来完美解决这个问题,本文将完成介绍@Async的用法。

  1. 何为异步调用?
    在解释异步调用之前,我们先来看同步调用的定义;同步就是整个处理过程顺序执行,当各个过程都执行完毕,并返回结果。异步调用则是只是发送了调用的指令,调用者无需等待被调用的方法完全执行完毕;而是继续执行下面的流程。
    例如, 在某个调用中,需要顺序调用 A, B, C三个过程方法;如他们都是同步调用,则需要将他们都顺序执行完毕之后,方算作过程执行完毕;如B为一个异步的调用方法,则在执行完A之后,调用B,并不等待B完成,而是执行开始调用C,待C执行完毕之后,就意味着这个过程执行完毕了。
  2. 常规的异步调用处理方式
    在Java中,一般在处理类似的场景之时,都是基于创建独立的线程去完成相应的异步调用逻辑,通过主线程和不同的线程之间的执行流程,从而在启动独立的线程之后,主线程继续执行而不会产生停滞等待的情况。

Spring 异步执行Async简介
Spring中用@Async注解标记的方法,称为异步方法,其实就相当于我们自己在当前方法里面:new Thread(()-> System.out.println("hello world !"))。%E6%8C%89@Async%E6%B3%A8%E8%A7%A3%E4%BD%BF%E7%94%A8%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%96%B9%E6%B3%95%EF%BC%9A
br/>按@Async注解使用的基本方法:
在方法上添加@Async注解;%E6%89%80%E4%BD%BF%E7%94%A8%E7%9A%84@Async%E6%B3%A8%E8%A7%A3%E6%96%B9%E6%B3%95%E7%9A%84%E7%B1%BB%E5%AF%B9%E8%B1%A1%E5%BA%94%E8%AF%A5%E6%98%AFSpring%E5%AE%B9%E5%99%A8%E7%AE%A1%E7%90%86%E7%9A%84bean%E5%AF%B9%E8%B1%A1%EF%BC%9B
br/>所使用的@Async注解方法的类对象应该是Spring容器管理的bean对象;
调用异步方法类上需要配置上注解@EnableAsync

Spring 异步执行Async示例

技术图片@EnableAsync%E7%9B%B8%E5%BD%93%E4%BA%8EAsyncConfigurationSelector%EF%BC%8C%E6%A0%B9%E6%8D%AE@Configuration%E4%B8%AD%E7%9A%84mode%E6%9D%A5%E5%86%B3%E5%AE%9A%E4%BA%A7%E7%94%9F%E5%BC%82%E6%AD%A5%E7%9A%84%E6%96%B9%E5%BC%8F%E6%98%AFProxyAsyncConfiguration%E8%BF%98%E6%98%AFAspectJAsyncConfiguration%EF%BC%8C%E9%BB%98%E8%AE%A4%E7%9A%84%E6%A8%A1%E5%BC%8F%E6%98%AFAdviceMode.PROXY%E3%80%82%E6%AD%A4%E6%97%B6%E6%B3%A8%E5%86%8C%E5%A4%84%E7%90%86bean%EF%BC%9AAsyncAnnotationBeanPostProcessor
br/>@EnableAsync相当于AsyncConfigurationSelector,根据@Configuration中的mode来决定产生异步的方式是ProxyAsyncConfiguration还是AspectJAsyncConfiguration,默认的模式是AdviceMode.PROXY。此时注册处理bean:AsyncAnnotationBeanPostProcessor
技术图片
执行程序后控制台输出

calling MyBean#runTask() thread: main
Running task thread: SimpleAsyncTaskExecutor-1
result from task: task result

Spring 异步执行Async之AsyncConfigurer

技术图片

async注解没有指定executor

  • 如果AsyncConfigurer没有定义executor,则会去寻找spring托管的名为taskExecutor的executor,如果没有,则抛出NoSuchBeanDefinitionException,返回null,然后由AsyncExecutionInterceptor.getDefaultExecutor去new一个SimpleAsyncTaskExecutor,不过这个不是spring托管的
  • 如果AsyncConfigurer定义了executor,则这个也不是spring托管的 不是spring托管的executor,需要自己额外去监听事件,然后优雅关闭

    总结

    在Spring中,@Async这个注解用于标记的异步的方法。方法上一旦标记了这个方法,当其它线程调用这个方法时,就会开启一个新的线程去异步处理业务逻辑。%E7%AE%80%E5%8D%95%E7%9A%84%E6%8A%8A@Async%E6%B3%A8%E8%A7%A3%E6%94%BE%E5%88%B0Bean%E7%9A%84%E6%96%B9%E6%B3%95%E4%B8%8A%E5%B0%B1%E4%BC%9A%E4%BD%BF%E7%94%A8%E4%B8%8D%E5%90%8C%E7%9A%84%E7%BA%BF%E7%A8%8B%E8%BF%90%E8%A1%8C%EF%BC%8C%E4%B9%9F%E5%B0%B1%E6%98%AF%E8%AF%B4%EF%BC%8C%E8%B0%83%E7%94%A8%E8%80%85%E6%89%A7%E8%A1%8C%E6%AD%A4%E6%96%B9%E6%B3%95%E4%B8%8D%E7%94%A8%E4%B8%80%E7%9B%B4%E7%AD%89%E5%BE%85%E6%95%B4%E4%B8%AA%E6%96%B9%E6%B3%95%E6%89%A7%E8%A1%8C%E5%AE%8C%E6%AF%95%E3%80%82
    br/>简单的把@Async注解放到Bean的方法上就会使用不同的线程运行,也就是说,调用者执行此方法不用一直等待整个方法执行完毕。
    在Spring中比较有趣的一点就是事件机制也支持异步处理,如果你想这样使用的话。
    让我们开始使用JAVA的注解配置开启异步处理机制,只需要简单的加上@EnableAsync注解到配置类上即可。

Spring 异步执行之@Async揭秘

标签:过程   sync   容器管理   基于   executor   java   and   aspectj   不用   

原文地址:https://blog.51cto.com/15015181/2556226


评论


亲,登录后才可以留言!