Okhttp的Interceptor攔截器源碼解析
OkHttp的調用流程:
在調用client.newCall(request)將會調用到RealCall.newRealCall(this, request, false);方法,之後將會調用到RealCall.getResponseWithInterceptorChain()函數,而在其中將進行攔截器鏈的構建。
RealCall.java
核心代碼:
Response result = getResponseWithInterceptorChain();
通過getResponseWithInterceptorChain完成對攔截器的構建
@Override public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
try {
client.dispatcher().executed(this);
Response result = getResponseWithInterceptorChain();
if (result == null) throw new IOException("Canceled");
return result;
} finally {
client.dispatcher().finished(this);
}
}
getResponseWithInterceptorChain()
包含自定義攔截器
重定向與失敗重試retryAndFollowUpInterceptor
用戶的請求頭處理,響應處理Cookie持久性策略 BridgeInterceptor
緩存請求、響應緩存的寫入 (客戶端設置的緩存策略)CacheInterceptor
發送請求,讀取服務器的響應CallServerInterceptor
最後通過RealInterceptorChain調用proceed接口啓動攔截器。
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
List<Interceptor> interceptors = new ArrayList<>();
interceptors.addAll(client.interceptors());
interceptors.add(retryAndFollowUpInterceptor);
interceptors.add(new BridgeInterceptor(client.cookieJar()));
interceptors.add(new CacheInterceptor(client.internalCache()));
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
interceptors.addAll(client.networkInterceptors());
}
interceptors.add(new CallServerInterceptor(forWebSocket));
Interceptor.Chain chain = new RealInterceptorChain(
interceptors, null, null, null, 0, originalRequest);
return chain.proceed(originalRequest);
}
幾個管件類和接口
Interceptor.java
public interface Interceptor {
Response intercept(Chain chain) throws IOException;
interface Chain {
Request request();
Response proceed(Request request) throws IOException;
Connection connection();
}
}
RealInterceptorChain.java
public final class RealInterceptorChain implements Interceptor.Chain {
private final List<Interceptor> interceptors;
private final StreamAllocation streamAllocation;
private final HttpCodec httpCodec;
private final Connection connection;
private final int index;
private final Request request;
private int calls;
public RealInterceptorChain(List<Interceptor> interceptors, StreamAllocation streamAllocation,
HttpCodec httpCodec, Connection connection, int index, Request request) {
this.interceptors = interceptors;
this.connection = connection;
this.streamAllocation = streamAllocation;
this.httpCodec = httpCodec;
this.index = index;
this.request = request;
}
...
@Override public Response proceed(Request request) throws IOException {
return proceed(request, streamAllocation, httpCodec, connection);
}
public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,
Connection connection) throws IOException {
...
// Call the next interceptor in the chain.
RealInterceptorChain next = new RealInterceptorChain(
interceptors, streamAllocation, httpCodec, connection, index + 1, request);
Interceptor interceptor = interceptors.get(index);
Response response = interceptor.intercept(next);
...
return response;
}
}
RealInterceptorChain實現了Interceptor接口,調用源頭來自於RealCall的getResponseWithInterceptorChain方法
調用流程:
1.加入自定義攔截器。然後將okhttp內置的一些攔截器按照功能順序add進list裏。
2.定義整個攔截器工作的源頭。new一個RealInterceptorChain,idnex爲0,把初始的request傳了進去,然後調用proceed獲取請求的response
3.RealInterceptorChain實現了Interceptor.Chain接口,在proceed方法中獲取上一個攔截器包裝的Request,然後將下一個攔截器和整個Request的信息包裝成RealInterceptorChain,並且會調用當前攔截器的intercept方法把下一個攔截器(RealInterceptorChain)傳進去,並且獲取到Response
4.CallServerInterceptor的Interceptor完成最終的網絡請求並返回response