RestTemplate源码解读
引言
SpringCloud的微服務均是以Http接口的形式來暴露自身服務的,因此在調用遠程服務的時候必須使用HTTP客戶端,可選的方案有JDK原生的URL Connection、Apache的Http Client、Netty的異步Http Client,Spring的RestTemplate和Fegin。
今天主要介紹一下Spring的RestTemplate。
源碼跟讀
通過源碼可以看到RestTemplate進行請求的很多方法最終調用的均是doExecute方法。
可以看出,主要分為創建請求Request,執行請求Request,處理返回結果response3個步驟。
創建請求
跟進createRequest()方法,發現該方法是由HttpAccessor負責實現的。
其基本思路是傳入請求地址url和請求方法method,然后由ClientHttpRequestFactory工廠負責Request的創建,ClientHttpRequestFactory為一個接口,其實現類主要有:
HttpAccessor提供了get/set方法,方便傳入不同的ClientHttpRequestFactory實現類,如果需要自定義ClientHttpRequestFactory工廠,直接implements ClientHttpRequestFactory復寫方法,然后注入HttpAccessor即可。
HttpAccessor默認使用的是SimpleClientHttpRequestFactory工廠實現類。
繼續跟進SimpleClientHttpRequestFactory工廠實現類。
它提供了兩種請求創建方法,分別支持同步和異步請求:
- createRequest(URI uri, HttpMethod httpMethod)
- createAsyncRequest(URI uri, HttpMethod httpMethod)
上述兩種方法均包括打開連接、準備連接、創建連接3個步驟。
先看openConnection方法,它的實現比較簡單,有代理Proxy存在,則傳入Proxy打開連接,否則則直接通過URL打來連接。
prepareConnection方法主要根據傳入的參數,進行連接前的一些配置工作,比如設置連接超時、讀取超時、根據不同請求method設置相應配置參數等。
最后創建連接的時候,根據bufferRequestBody是否為True,創建2種不同的連接,分別為批處理連接和流處理連接。
return (ClientHttpRequest)(this.bufferRequestBody ? new SimpleBufferingClientHttpRequest(connection, this.outputStreaming) : new SimpleStreamingClientHttpRequest(connection, this.chunkSize, this.outputStreaming));執行請求
切回到RestTemplate類的doExecute方法,可以看到建立http連接,拿到ClientHttpRequest后,執行請求的方法為execute()。
ClientHttpRequest為接口,僅有一個execute()方法,看一下ClientHttpRequest的實現類:
其中用的比較多的是AbstractClientHttpRequest抽象類,SimpleStreamingClientHttpRequest和SimpleBufferingClientHttpRequest分別繼承了AbstractClientHttpRequest,復寫某些方法以支持流/批處理請求。
跟進AbstractClientHttpRequest抽象類的execute()方法,
execute()內部調用的是executeInternal(),由子類來具體實現,可以看一下SimpleBufferingClientHttpRequest的方法實現,其他子類實現方式大同小異。
可以看到,主要是做了一些添加請求頭、返回設置等的操作,最后得到請求的返回類SimpleClientHttpResponse。
至此,我們就拿到請求的返回了,下一步就是處理返回結果了。
處理返回結果
返回結果處理主要分為兩步:
- handleResponse(url, method, response)
- responseExtractor.extractData(response)
其中,handleResponse(url, method, response)主要負責對請求的異常進行處理。
可以看到,handleResponse()方法首先獲取請求錯誤的處理器errorHandler,然后把response交給它進行后續的處理。
而responseExtractor.extractData(response)主要負責返回數據的解析。
responseExtractor為接口,其實現類為:
其中ResponseEntityResponseExtractor和HeadersExtractor為RestTemplate的內部類,主要處理返回的headers和entity,我們重點關注返回消息的轉化處理類HttpMessageConverterExtractor。
可以看到,extractData先將response交給responseWrapper,如果responseWrapper有消息體且非空,則進行返回消息的讀取操作。
消息的讀取需要借助HttpMessageConverter接口,HttpMessageConverter具有多種實現類,以完成不同格式消息的讀取,相當于消息解碼器或轉換頭。
可以看到,在構建HttpMessageConverterExtractor實例的時候,需要傳入HttpMessageConverter的接口集合messageConverters,用于對不同返回格式消息的讀取。
首先,得到messageConverters的迭代器,然后遍歷迭代器,依次執行不同HttpMessageConverter讀取操作,最終完成返回消息體的讀取操作。
迭代過程中,如果當前MessageConverter屬于GenericHttpMessageConverter的接口實現,則執行:
return genericMessageConverter.read(this.responseType, (Class)null, responseWrapper);否則:
return messageConverter.read(this.responseClass, responseWrapper);總結
-
RestTemplate是Spring提供的用于訪問Rest服務的客戶端;
-
RestTemplate提供了多種便捷訪問遠程Http服務的方法,能夠大大提高客戶端的編寫效率;
-
調用RestTemplate的默認構造函數,RestTemplate對象在底層通過使用java.net包下的實現創建HTTP請求;
-
可以通過使用ClientHttpRequestFactory指定不同的HTTP請求方式;
-
在設計模式上,主要通過工廠模式來完成各類Http客戶端的創建。
歡迎您掃一掃上面的二維碼,關注我的微信公眾號!
總結
以上是生活随笔為你收集整理的RestTemplate源码解读的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Foobar2000 封面显示个性
- 下一篇: 弱人脉与弱关系