首页 > 解决方案 > 在 @Async 方法中通过 Spring RestTemplate 调用 Rest API

问题描述

据我所知,Spring RestTemplate是同步的并阻塞线程,直到 Web 客户端收到响应,而 Spring WebClient是异步且非阻塞的。

但是,如果我们在@Async注释方法中使用RestTemplate调用 API 会怎样?

它会阻止@Async创建的新线程吗?

最后,您对 Rest API 的异步调用有什么建议(没有WebClient,因为我使用的是早于 5 的 Spring 版本)。谢谢

标签: springspring-mvcspring-webclientspring-asyncspring-resttemplate

解决方案


如果我们在带@Async注释的方法中使用 RestTemplate 调用 API 会怎样?

@Async该方法将在您在注释参数中指定的执行器上异步运行。例如@Async("threadPool"),其中“threadPool”是 Executor bean 的名称。

它会阻止@Async 创建的新线程吗?

是的,它会阻塞 Spring 运行你的方法的线程。但是,线程不一定是由 Spring 创建的,它可以从您在@Async注释中定义的线程池中获取。

你对 Rest API 的异步调用有什么建议(没有 WebClient,因为我使用的是早于 5 的 Spring 版本)?

您可以使用 CompletableFuture API,或者@Async如果您只需要“异步”效果。但是,如果您还需要“非阻塞”属性,则需要使用一些非阻塞 HTTP 客户端,例如okhttp

使用 okhttp 的非阻塞异步 HTTP 调用如下所示:

public CompletableFuture<Response> call() {
  Request request = new Request.Builder()
    .url(URL)
    .build();
  Call call = client.newCall(request);
  CompletableFuture<Response> result = new CompletableFuture<>();
  call.enqueue(new Callback() {
    public void onResponse(Call call, Response response) throws IOException {
      result.complete(response);
    }
    public void onFailure(Call call, IOException e) {
      result.completeExceptionally(e);
    }
  });
  return result;
}

推荐阅读