使用 Spring @Async 与直接使用 CompleteableFuture 相比有什么优势?

问题描述 投票:0回答:3

使用 Spring Async 与仅返回

CompletableFuture
相比有什么优势?

java spring asynchronous java-8 completable-future
3个回答
40
投票

两者之间不存在“vs.”——这些是互补技术:

  • CompletableFuture
    提供了一种便捷的方法来链接异步计算的不同阶段 - 比 Spring 的
    ListenableFuture
    ;
  • 更灵活
  • @Async
    为您的执行器提供标准 Spring 配置,方便管理后台任务和线程。

但两者可以结合起来(自 Spring 4.2)。假设您想将以下方法变成返回

CompletableFuture
的后台任务:

public String compute() {
    // do something slow
    return "my result";
}

你必须做什么:

  • 如果尚未完成:使用
    @EnableAsync
    Executor
    bean
  • 配置您的应用程序
  • @Async
  • 注释该方法
  • 将其结果包装成
    CompletableFuture.completedFuture()
@Async
public CompletableFuture<String> computeAsync() {
    // do something slow - no change to this part
    // note: no need to wrap your code in a lambda/method reference,
    //       no need to bother about executor handling
    return CompletableFuture.completedFuture("my result");
}

正如您所注意到的,您不必费心将后台任务提交给执行器:Spring 会为您处理这件事。您只需将结果包装成完整的

CompletableFuture
,以便签名与调用者期望的相匹配。

其实这相当于:

@Autowire
private Executor executor;

public CompletableFuture<String> computeAsync() {
    return CompletableFuture.supplyAsync(() -> {
        // do something slow
        return "my result";
    }, executor);
}

但它消除了以下需要:

  • 注入执行器
  • supplyAsync()
    通话中与执行者打交道
  • 将逻辑包装在 lambda 中(或将其提取到单独的方法中)

24
投票

您的应用程序由容器管理。由于不鼓励您自己生成

Thread
,因此您可以让容器注入托管
Executor

@Service
class MyService {
  @Autowired
  private Executor executor;

  public CompletableFuture<?> compute() {
    return CompletableFuture.supplyAsync(() -> /* compute value */, executor);
  }
}

0
投票

@Async
在Spring应用程序中更节省。在 Spring 应用程序中使用
CompletableFuture
可能很危险。线程不是由 Spring 创建的,也不是继承自 Spring 自己配置的
ClassLoader
。这样,类的动态加载可能会在运行时在
CompletableFuture
执行块内失败。请参阅 CompletableFuture / ForkJoinPool 设置类加载器

© www.soinside.com 2019 - 2024. All rights reserved.