前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring框架中的异步执行

Spring框架中的异步执行

作者头像
Bug开发工程师
发布2019-12-31 15:47:30
8230
发布2019-12-31 15:47:30
举报
文章被收录于专栏:码农沉思录

一、Spring框架中的异步执行

在Spring Framework中分别使用TaskExecutor和TaskScheduler接口提供异步执行和任务调度的抽象,本节我们着重讲解基于TaskExecutor支撑的的注解@Async如何实现异步处理的。

二、 @Async注解异步处理原理

在Spring中可以在方法上添加@Async注释,以便异步调用该方法。换句话说,调用者将在调用含有@Async注释的方法时立即返回,并且该方法的实际执行将发生在Spring TaskExecutor异步处理器线程中。需要注意的是该注解@Async默认是不会解析的,SpringBoot中需要加上@EnableAsync来启动。

下面我们看如何使用@Async注解进行异步处理,如下代码:

代码语言:javascript
复制
@Async
    public void dosomthingAsync() {

        System.out.println("--dosomthingAsync begin---");
        // 模拟异步处理
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("--dosomthingAsync end---");
    }

如上代码在方法dosomthingAsync上添加了@Async的注解,所以当我们调用dosomthingAsync方法时候,该方法会马上返回。

另外使用@Async可以有返回值,因为它们将在运行时由调用者以“正常”方式调用,而不是由容器管理的调度任务TaskExecutor自动调用。例如,以下是使用@Async注解的合法方法:

代码语言:javascript
复制
@Component
public class AsyncTask {
...
    @Async
    public CompletableFuture<String> dosomthingAsyncFuture() {

        System.out.println("--dosomthingAsync begin---");
        CompletableFuture<String> future = new CompletableFuture<String>();

        // 模拟异步处理
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        future.complete("ok");
        System.out.println("--dosomthingAsync end---");

        return future;
    }
}

如上代码调用该方法后,该方法会马上返回一个CompletableFuture对象,如果你一直持有这个CompletableFuture对象,那么等dosomthingAsyncFuture内业务处理异步处理完毕后,就可以从dosomthingAsyncFuture的get()方法获取到执行结果。

那么Spring框架是如何做到我们dosomthingAsyncFuture时候会马上返回一个CompletableFuture那?其实其对该类进行了代理,经过代理后的上面的方法类似于:

代码语言:javascript
复制
public class AsynTaskProxy {

    public AsyncTask getAsyncTask() {
        return asyncTask;
    }

    public void setAsyncTask(AsyncTask asyncTask) {
        this.asyncTask = asyncTask;
    }

    private AsyncTask asyncTask;

    private TaskExecutor executor = new SimpleAsyncTaskExecutor();

    public CompletableFuture<String> dosomthingAsyncFuture() {

        return CompletableFuture.supplyAsync(new Supplier<String>() {

            @Override
            public String get() {
                try {
                    return asyncTask.dosomthingAsyncFuture().get();
                } catch (Throwable e) {
                    throw new CompletionException(e);
                }
            }
        },executor);
    }
}

Spring会对AsyncTask类使用类似的AsynTaskProxy进行代理,并且会把AsynTask的实例注入到AsynTaskProxy内部,当我们调用AsynTask的dosomthingAsyncFuture方法时候,实际调用的是AsynTaskProxy的dosomthingAsyncFuture方法,后者则使用 CompletableFuture.supplyAsync开启了一个异步任务(其马上返回一个 CompletableFuture对象),并且使用默认的SimpleAsyncTaskExecutor线程池做为异步处理线程,然后异步任务内在具体调用了 AsyncTask实例的dosomthingAsyncFuture方法,并且在返回的future上获取执行结果。

更深入的细节读者可以翻看AsyncExecutionInterceptor代码进行研究。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-12-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农沉思录 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、Spring框架中的异步执行
  • 二、 @Async注解异步处理原理
  • 更深入的细节读者可以翻看AsyncExecutionInterceptor代码进行研究。
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档