Spring中的RestTemplate原始碼分析

2021-10-05 18:56:04 字數 4669 閱讀 9209

之前有一篇文章是分析的feign, 這邊文章來分析spring中的resttemplate,下面還會有一篇來分析最新的webclient,當然這時後話,下面來具體看一下resttemplate的執行流程。

get請求流程分析(getforobject)

首先從get方法開始,傳入url,返回型別,引數即可,方法原型:

public t getforobject(string url, classresponsetype, mapurivariables) throws restclientexception
看到他先建立了乙個requestcallback型別變數,那麼這個是什麼呢?

requestcallback是乙個功能介面(functionalinte***ce),裡面只有乙個方法宣告:

void dowithrequest(clienthttprequest request) throws ioexception;
它是用來操作request的,在請求傳送前,為請求新增header,將請求體寫入request。

它有兩個實現類,乙個是acceptheaderrequestcallback實現requestcalback,為請求新增請求頭;另乙個是httpentityrequestcallback,繼承自acceptheaderrequestcallback,為請求新增請求頭,寫入請求體。對於get請求它使用的是acceptheaderrequestcallback,即只需要處理請求頭,因為get請求並沒有請求體。

新建完requestcallback後又新建了httpmessageconverterextractor型別變數,這個主要是從response中獲取並轉換返回物件用的,後面會說到。

在這裡它只作了乙個工作,根據urlvariables中的鍵值對,替換url中的佔位符,並轉換為uri物件,然後進入方法doexecute,這一步是它的核心邏輯所在:

} }首先根據url和method引數建立request物件,跟進方法檢視:

}可以看到它是呼叫了requestfactory來建立request物件,而requestfactory這個屬性有乙個預設值,屬性簽名如下:

private clienthttprequestfactory requestfactory = new ******clienthttprequestfactory()
進入它的createrequest方法:

}可以看到它是用了jdk中的httpurlconnection來建立連線,獲取返回值,而request物件型別根據是否快取reqeustbody分為******bufferingclienthttprequest******streamingclienthttprequest兩種型別,預設bufferrequestbody==true,即預設request型別為******bufferingclienthttprequest

回到上一步,在建立完請求後,在傳送請求之前還需要設定請求頭和請求體,即應用requestcallback,然後呼叫execute方法,這裡即呼叫httpurlconnection來執行請求,它會返回乙個******clienthttpresponse型別物件,接下來就需要處理這個返回值。

對於這個response,首先是呼叫handleresponse方法來判斷請求是否有異常(根據狀態碼來判斷):

}如果有異常則呼叫errorhandler來處理,預設errorhandler型別為defaultresponseerrorhandler,它的處理方法是丟擲異常,如果這裡丟擲異常則執行流程結束,不會再解析返回值。

如果沒有異常則呼叫responseextractor來抽取返回值或者響應頭(header),對於get方法,預設的responseextractor型別是httpmessageconverterextractor,它會轉換response物件為指定的返回型別t,之後返回這個轉換後的物件出去即可以。

getforentity

上面講的是getforobject方法,那麼getforentity方法呢,其實他們的區別就是傳入的responseextractor型別不同,getforobject傳入的是httpmessageconverterextractor, 而getforentity傳入的是responseextractor>,而這個responseextractor>只是在httpmessageconverterextractor上封裝了乙個轉換操作,構造方法如下:

public responseentityresponseextractor(@nullable type responsetype) 

else

}

extractdata方法裡可以看到也只是把返回值t包裝在了responseentity物件裡:

} }post請求?

那麼post方法呢?以postforobject為例:

public t postforobject(string url, @nullable object request, classresponsetype,

mapurivariables) throws restclientexception

它和get的主要區別就是requestcallback實際使用的型別是httpentityrequestcallback,即寫入請求頭也寫入請求體,其他並無二致。

其他resttemplate類圖:

get請求的活**:

Spring複習筆記 Spring中的Bean

注意構造器例項化 最常用 靜態工廠方式例項化 例項工廠方式例項化 singleton 單例 始終使用的同乙個物件 預設 prototype 原型 每次都是乙個新的bean例項 request session globalsession websocket init method屬性 用於指定bean...

Spring基礎 Spring中的AOP框架

oop 物件導向程式設計 提供 從上到下 的關係,而aop 面向方面程式設計 提供一種 橫切 的方式,也可以說是 從左到右 簡單來說就是將那些與業務無關,卻為業務模組所共同呼叫的邏輯或責任封裝起來,便於減少系統的重複 降低模組間的耦合度,並有利於未來的可操作性和可維護性。可能光是說aop的定義,大家...

Spring中的QuartzJobBean的使用

一 quartz的特點 按作業類的繼承方式來分,主要有以下兩種 1.作業類繼承org.springframework.scheduling.quartz.quartzjobbean類的方式 2.作業類不繼承org.springframework.scheduling.quartz.quartzjob...