SpringMVC异步处理的 5 种方式示例详解

针对“SpringMVC异步处理的 5 种方式示例详解”的完整攻略,我将从以下几个方面进行详细讲解:

  1. 什么是SpringMVC异步处理
  2. SpringMVC异步处理的5种方式
  3. 异步处理方式的示例说明
  4. 总结

1. 什么是SpringMVC异步处理

在SpringMVC中,一般的请求处理是同步的,也就是说请求到达后一直会占用线程,等待响应并返回结果。但是面对一些复杂的请求时,这种同步的方式就显得捉襟见肘了,比如长时间的文件上传和下载、查询复杂耗时的SQL、查询Web Service等。因此,SpringMVC为了更好的解决适合异步处理的请求,提出了异步处理的机制,使得这些请求需要等待的时间大大缩短。

2. SpringMVC异步处理的5种方式

SpringMVC异步处理主要有以下5种方式:

  1. 使用DeferredResult
  2. 使用Callable
  3. 使用ListenableFuture
  4. 使用CompletableFuture
  5. 使用Servlet 3.0

接下来我将分别对这5种方式进行详细讲解。

2.1 使用DeferredResult

使用DeferredResult是SpringMVC提供的一种异步非阻塞返回结果的方式,通过使用它,控制器线程可以先响应并返回空的DeferredResult对象,这个DeferredResult的结果在另外一个线程中计算并设置,当计算完成后,DeferredResult会携带计算出来的结果响应客户端。

2.2 使用Callable

Callable是Java并发包提供的类,能够异步执行一个任务并返回结果,类似于Runnable,但有返回值。在SpringMVC中使用Callable的原理与DeferredResult类似,当控制器线程遇到Callable时,会先执行并返回一个Callable对象,然后再启动一个新的线程来执行Callable,返回结果后,该线程又会转回控制器线程来响应客户端请求。

2.3 使用ListenableFuture

ListenableFuture基于Guava库,与DeferredResult类似,它也能够异步处理,只是操作更加灵活。通过ListenableFuture,可以在异步执行结束后立即执行一些操作,而不用像DeferredResult一样通过回调函数来操作。

2.4 使用CompletableFuture

CompletableFuture也是Java的一个异步处理类,在Java8中引入了这个类。它相比DeferredResult和ListenableFuture更加强大,并且也支持异步触发回调函数。

2.5 使用Servlet 3.0

Servlet 3.0提供的异步处理方式相对于前面的4种方式,更加简单直接。在Servlet 3.0中,只需要给异步处理的请求设置一个AsyncContext异步上下文,便能够异步返回结果。

3. 异步处理方式的示例说明

现在,让我们通过两个示例,分别来说明两种异步处理方式:使用DeferredResult和使用CompletableFuture。

3.1 使用DeferredResult

以使用DeferredResult处理下载文件请求为例,如下:

@GetMapping("/download")
@ResponseBody
public DeferredResult<byte[]> download(final int delay) {
    final DeferredResult<byte[]> deferredResult = new DeferredResult<>(60000L);//设置60s的超时返回结果

    // 新起一个线程异步执行文件下载
    new Thread(() -> {
        try {
            byte[] fileByte = fileService.download(delay);
            //计算文件hash值
            String fileMd5 = DigestUtils.md5Hex(fileByte);
            //设置DeferredResult结果
            deferredResult.setResult(fileByte);
        } catch (Throwable t) {
            deferredResult.setErrorResult(t);
        }
    }).start();

    return deferredResult;
}

这个例子中,当用户请求下载文件时,由于文件下载的时间比较长,为了避免这个请求一直占用线程,我们就需要使用DeferredResult。实现的原理和我们前面的介绍中一样,先响应一个空DeferredResult对象,等待后续计算,计算完毕后再回调设置DeferredResult的结果。

当我们使用浏览器访问该地址时,由于异步执行文件下载,因此页面不会直接以文件形式下载,而是等待60秒,然后将下载的文件返回。

3.2 使用CompletableFuture

接下来,我们再介绍一下如何使用CompletableFuture异步处理请求。以查询Web Service为例:

@GetMapping("/webService")
@ResponseBody
public CompletableFuture<Result> callWebService() {
    return CompletableFuture.supplyAsync(() -> {
        Result result = webService.callWebService(); //调用WebService接口
        return result;
    });
}

如果Web service调用返回的结果比较缓慢,当前线程会一直阻塞,无法响应其他请求,因此我们需要使用CompletableFuture,并使用它提供的异步回调,通过新起一个线程异步调用Web service接口。

4. 总结

SpringMVC提供的异步处理机制,能够让SpringMVC更加高效地处理一些长时间等待的请求,提高系统的响应速度和效率。SpringMVC提供了5种异步处理的方式,包括使用DeferredResult、Callable、ListenableFuture、CompletableFuture和Servlet 3.0,不同的异步处理方式有不同的特点和使用场景,我们可以根据需要自行选择。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringMVC异步处理的 5 种方式示例详解 - Python技术站

(0)
上一篇 2023年5月16日
下一篇 2023年5月16日

相关文章

  • IDEA中创建maven项目引入相关依赖无法下载jar问题及解决方案

    下面是详细讲解“IDEA中创建maven项目引入相关依赖无法下载jar问题及解决方案”的完整攻略。 问题描述 在使用IntelliJ IDEA创建Maven项目时,通过编辑POM.XML文件引入相关依赖,但是发现IDEA无法下载所需的JAR包,导致项目无法编译运行。 可能原因 上述依赖库不存在。 依赖库被墙了。 IDEA配置问题。 解决方案 方案一:更改本地…

    Java 2023年5月19日
    00
  • Java花式解决’分割回文串 ii’问题详解

    对于Java花式解决’分割回文串 ii’问题详解,我将从以下几个方面进行讲解: 问题描述 解题思路 实现代码 示例说明 1. 问题描述 给定一个字符串s,将s分割成若干个非空回文子串,使得每个子串都是回文串。求最少需要分割几次。 2. 解题思路 本题可以使用动态规划来求解。定义dp[i]表示前缀s[0…i]最少需要切几次,才能满足每个子串都是回文串。那么…

    Java 2023年5月27日
    00
  • 使用Get方式提交数据到Tomcat服务器的方法

    下面是使用Get方式提交数据到Tomcat服务器的方法的完整攻略: 1. Get方式提交数据概述 在使用Get方式提交数据到Tomcat服务器之前,我们需要了解一下Get方式提交数据的基本概念,以及它和Post方式提交数据的区别。Get方式提交数据是指将数据塞入URL之中,浏览器将连接信息、参数信息和HTTP首部一起发送给服务器。相比较而言,Post方式提交…

    Java 2023年5月19日
    00
  • jsp输出九九乘法表的简单实例

    我将为您详细讲解“JSP输出九九乘法表的简单实例”的攻略: 前置条件: 需要安装本地的 Java 和 Tomcat 环境,同时需要了解基本的 JSP 开发知识。 创建 JSP 页面 首先,我们需要在 Tomcat 中创建一个 JSP 页面,用于输出九九乘法表。可以在本地的 Tomcat 服务器中的 webapps 目录下创建一个新的文件夹(例如叫做“jmf”…

    Java 2023年6月15日
    00
  • java的Hibernate框架报错“NonUniqueObjectException”的原因和解决方法

    当使用Hibernate框架时,可能会遇到“NonUniqueObjectException”错误。这个错误通常是由于以下原因之一引起的: 多个实体对象具有相同的标识符:如果您的多个实体对象具有相同的标识符,则可能会出现此错误。在这种情况下,需要检查您的实体对象并确保它们具有唯一的标识符。 会话中存在多个实体对象:如果您的会话中存在多个实体对象,则可能会出现…

    Java 2023年5月4日
    00
  • Java实现茶叶售卖商城系统(java+SSM+JSP+EasyUi+mysql)

    首先我们需要明确这个系统的功能和技术栈:Java实现茶叶售卖商城系统,技术栈包括Java、SSM框架、 JSP、EasyUI以及MySQL数据库。 下面将从需求分析、技术环境搭建、功能实现和项目测试等方面来进行讲解这个系统的攻略: 一、需求分析 在开始搭建系统之前,我们需要对系统的需求进行彻底的分析和定义,这样才能更好地实现系统的功能。 基于需求分析,我们可…

    Java 2023年5月24日
    00
  • java使用分隔符连接数组中每个元素的实例

    下面我将为你详细讲解Java中使用分隔符连接数组中每个元素的实例,主要包括以下内容: String中的join方法 StringBuilder/StringBuffer 1. String中的join方法 String中的join方法可以方便地将一个数组或集合中的元素以指定的分隔符连接起来。它的语法为: public static String join(C…

    Java 2023年5月26日
    00
  • Java多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask详解

    Java多线程下的其他组件之CyclicBarrier CyclicBarrier概述 CyclicBarrier是Java中一个同步工具类,用于在多线程中等待所有线程到达某个同步点,然后再一起执行后续操作,这个同步点就是所谓的屏障(barrier),它可重用,即当到达屏障的线程数量达到指定值时,所有线程都可以通过屏障,继续执行下一个操作。 CyclicBa…

    Java 2023年5月18日
    00
合作推广
合作推广
分享本页
返回顶部