2015-10-13 59 views
2

今天我在AsyncRestTemplate上做了一些实验。下面是一块示例代码:AsyncRestTemplate何时发送请求?

ListenableFuture<ResponseEntity<MyObject[]>> result 
          = asyncRestTemplate.getForEntity(uri, MyObject[]); 
List<MyObject> objects = Arrays.asList(result.get().getBody()); 

令我惊讶的,该请求未发送至在第一行URI(即主叫getForEntity后),但result.get后发送()被调用。

这不是一种同步的做事方式吗?

+0

它正在第一行开始请求。 (确切地说,它只是安排请求,很可能没有实际的HTTP流量后,该行代码呢:) – zapl

+1

嗨,我今天做了一些测试,确认AsyncRestTemplate发送请求将调用get()或addCallback() ,而不是在调用getForEntity()或exchange()等时。 –

回答

0

当你打电话给future.get()你基本上是通过等待结果将异步操作变成同步操作。

执行实际请求时无关紧要,重要的是由于它是异步的,因此除非需要结果,否则不必担心它。

当您在处理结果之前需要执行其他工作,或者根本没有等待结果时,优势显而易见。

2

执行异步请求的整个想法是,要么不等待异步任务启动/完成,要么希望主线程在请求​​Future实例的结果之前执行其他任务。 AsyncRestTemplate在内部准备一个AsyncRequest并调用executeAsync方法。

AsyncClientHttpRequest request = createAsyncRequest(url, method); 
      if (requestCallback != null) { 
       requestCallback.doWithRequest(request); 
      } 
      ListenableFuture<ClientHttpResponse> responseFuture = request.executeAsync(); 

有两种不同的实现 - HttpComponentsAsyncClientHttpRequest(其使用在Apache http component库中提供高高性能异步支持)SimpleBufferingAsyncClientHttpRequest和(其使用由J2SE类提供设施)。在HttpComponentsAsyncClientHttpRequest的情况下,它内部有一个线程工厂(这不是春天管理的AFAIK),而在SimpleBufferingAsyncClientHttpRequest中,有一个提供了Spring管理的AsyncListenableTaskExecutor。总而言之,在所有情况下都有一些ExecutorService能够异步运行任务。当然,对于这些线程池来说很自然,任务的实际启动时间是不确定的,并且取决于许多因素,如负载,可用的CPU等等,不应该依赖它。