RetryAndFollowUpInterceptor 實現(xiàn)原理和功能分析
Overview
該攔截器功能有
* 創(chuàng)建Address
* 創(chuàng)建StreamAllocation
* 處理響應(yīng)結(jié)果,例如重定向或者重試
這個類最核心的方法就是它的
```java
@Override public Response intercept(Chain chain) throws IOException
```
這個Chain是在RealCall中的 getResponseWithInterceptorChain()構(gòu)造并傳入的庆械。
下面是該方法的實現(xiàn)
1.創(chuàng)建Address和StreamAllocation
```java
private Address createAddress(HttpUrl url) {
SSLSocketFactory sslSocketFactory = null;
HostnameVerifier hostnameVerifier = null;
CertificatePinner certificatePinner = null;
if (url.isHttps()) {
sslSocketFactory = client.sslSocketFactory();
hostnameVerifier = client.hostnameVerifier();
certificatePinner = client.certificatePinner();
}
return new Address(url.host(), url.port(), client.dns(), client.socketFactory(),
sslSocketFactory, hostnameVerifier, certificatePinner, client.proxyAuthenticator(),
client.proxy(), client.protocols(), client.connectionSpecs(), client.proxySelector());
}
```
通過此代碼創(chuàng)建一個Address气堕,然后創(chuàng)建一個StreamAllocation苔悦,這個類算是OkHttp的核心類柠偶,創(chuàng)建Socket和連接Socket都在這個類當中。
2.執(zhí)行chain.proceed()
```
response = ((RealInterceptorChain) chain).proceed(request, streamAllocation, null, null);
releaseConnection = false;
```
將Request和構(gòu)建好的streamAllocation傳遞給后面的interceptor,并返回Response
3.處理響應(yīng)結(jié)果瀑志,例如重定向或者重試
得到Response霉咨,根據(jù)響應(yīng)狀態(tài)做響應(yīng)的處理
怎么實現(xiàn)重定向和重試的?
這是其 public Response intercept(Chain chain) 的一段大致流程代碼拇派,
這段代碼不是源碼荷辕,是我在源碼的基礎(chǔ)上認為比較重要的復(fù)制出來拼在一起的
很佩服作者的思路,真的很巧妙件豌。
用一個死循環(huán)來做的疮方,重定向是根據(jù)結(jié)果返回的的來決定是否需要跳出死循環(huán),
重試是根據(jù)拋出的IOException的時候判斷是將異常拋出還是繼續(xù)執(zhí)行循環(huán)來做的
```
while (true){
//proceed
try {
response = chain.proceed(request, streamAllocation, null, null)
}catch (IOException e) {
boolean requestSendStarted = !(e instanceof ConnectionShutdownException);
//這是其中的一個異常處理 茧彤,recover是判斷時候需要重試骡显,若需要重試繼續(xù)循環(huán),不需要則拋出異常退出循環(huán)
if (!recover(e, requestSendStarted, request)) throw e;
releaseConnection = false;
continue;
}
//根據(jù)response判斷是否需要重定向 曾掂,不要返回null 需要返回重定向的Request
Request followUp = followUpRequest(response)
//不需要重定向 返回response
if (followUp == null){
return response
}
//是否達到最大允許的重定向次數(shù)
if (++followUpCount > MAX_FOLLOW_UPS) {
streamAllocation.release()
throw ProtocolException("Too many follow-up requests: " + followUpCount)
}
//重新構(gòu)建streamAllocation
if (!sameConnection(response, followUp.url())) {
streamAllocation.release();
streamAllocation = new StreamAllocation(
client.connectionPool(), createAddress(followUp.url()), callStackTrace);
} else if (streamAllocation.codec() != null) {
throw new IllegalStateException("Closing the body of " + response
+ " didn't close its backing stream. Bad interceptor?");
}
接著循環(huán)
}
```
End 到此這個類的功能原理就很清楚了
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者