开发者

Spring中DeferredResult异步处理

开发者 https://www.devze.com 2023-12-07 10:21 出处:网络 作者: 檀越剑指大厂
目录一.简单介绍1.DeferredResult 简介2.功能和特性二.使用方式1.Controller 中的方法2.异步任务完成后设置结果3.自定义线程池三.原理分析1.Servlet 异步支持2.DeferredResult 中介四.注意事项1.超时处理2.异常处理3
目录
  • 一.简单介绍
    • 1.DeferredResult 简介
    • 2.功能和特性
  • 二.使用方式
    • 1.Controller 中的方法
    • 2.异步任务完成后设置结果
    • 3.自定义线程池
  • 三.原理分析
    • 1.Servlet 异步支持
    • 2.DeferredResult 中介
  • 四.注意事项
    • 1.超时处理
    • 2.异常处理
    • 3.不适用于所有场景

一.简单介绍

1.DeferredResult 简介

DeferredResult 是 Spring Framework 中用于异步处理请求的一种机制。它允许将处理结果推迟到稍后的时间点,通常用于处理需要较长时间完成的操作,例如异步任务、长时间计算或外部服务调用。

2.功能和特性

  • 异步处理: DeferredResult 允许将请求的处理推迟到稍后的时间,允许应用程序异步地处理请求。

  • 非阻塞: 使编程客栈用 DeferredResult 不会阻塞容器线程,这有助于提高应用程序的吞吐量。

  • 长轮询: 可以使用 DeferredResult 实现长轮询(long polling)模式,其中客户端发送请求并在服务器端保持挂起状态,直到有数据可用。

二.使用方式

1.Controller 中的方法

Controller 中的方法: 在控制器方法中,返回类型可以是 DeferredResult<T>,其中 T 是要返回的数据类型。

@GetMapping("/async-operation")
public DeferredResult<String> asyncOperation() {
    DeferredResult<String> deferredResult = new DeferredResult<>();

    // 在某个异步任务完成后,将结果设置到 DeferredResult 中
    asyncService.performAsyncOperation()
                .whenComplete((result, throwable) -> deferredResult.setResult(result));

    return deferpythonredResult;
}

2.异步任务完成后设置结果

异步任务完成后设置结果: 在异步任务完成后,通过 DeferredResult.setResult(result) 将结果设置到 DeferredResult 对象中。

public CompletableFuture<String> performAsyncOkNqWlVGdperation() {
    // 异步任务逻辑
    return CompletableFuture.supplyAsync(() -> "Async operation result");
}

3.自定义线程池

线程池:

public class ThreadPoolUntil {
    private static final int THREAD_POOL_SIZE = 10;
    private static ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE);

    public static void executeTask(Runnable task) {
        executorService.submit(task);
    }

    public static void shutdown() {
        executorService.shutdown();
    }
}

controller:

@ApiOperation(value = "首页-合计列表", nickname = "首页-合计列表")
@PostMapping("/totalList")
public DeferredResult<Payload<List<TotalListDayDTO>>> totalList(@RequestBody TotalListQuery totalListQuery
        , @RequestHeader(value = "brandDetailNo") String brandDetailNo) {
      totalListQuery.setBrandDetailNo(brandDetailNo);
      DeferredResult<Payload<List<TotalListDayDTO>>> deferredResult = new DeferredResult<>(10000L);
      // 设置超时处理
      deferredResult.onTimeout(() -> deferredResult.setErrorResult(new Payload("504", "请求超时")));
      // 设置错误处理
      deferredResult.onError((Throwable t) -> deferredResult.setErrorResult(new Payload("500", "系统错误")));
      // 创建任务
      Runnable task = () -> deferredResult.setResult(new Payload(skuDataBusinessService.totalList(totalListQuery)));
      ThreadPoolUntil.executeTask(task);
      return deferredResult;
}

三.原理分析

1.Servlet 异步支持

Servlet 3.0+ 异步支持: DeferredResult 的实现依赖于 Servlet 3.0+ 的异步支持。在处理请求时,容器会将请求转交给异步处理,允许处理线程在异步操作完成前释放。

2.DeferredResult 中介

DeferredResult 作为中介: Deferhttp://www.devze.comredResult 充当控制器方法和异步任务之间的中介,使得控制器方法可以在异步任务完成后设置结果。

四.注意事项

1.超时处理

超时处理: 可以设置 DeferredResult 的超时时间,如果异步操作在超时时间内未完成,可以通过设置超时处理逻辑来处理。

deferredResult.setTimeout(5000编程客栈); // 设置超时时间为5秒
deferredResult.onTimeout(() -> {
    // 处理超时逻辑
    deferredResult.setErrorResult("Operation timed out");
});

2.异常处理

异常处理: 需要在异步任务中捕获可能的异常,并在 DeferredResult 中设置错误结果。

asyncService.performAsyncOperation()
            .whenComplete((result, throwable) -> {
                if (throwable != null) {
                    deferredResult.setErrorResult("An error occurred: " + throwable.getMessage());
                } else {
                    deferredResult.setResult(result);
                }
            });

3.不适用于所有场景

不适用于所有场景: DeferredResult 适用于长时间运行的操作,但并不是适用于所有场景。对于一些简单和快速的操作,同步处理可能更加合适。

总体而言,DeferredResult 是 Spring 中处理异步请求的强大工具,可以帮助改善应用程序的性能和用户体验,特别是在需要处理长时间运行操作的情况下。

到此这篇关于Spring中DeferredResult异步处理的文章就介绍到这了,更多相关Spring DeferredResult异步内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号