2015-10-13 129 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等等,不應該依賴它。