Okhttp源碼解析(三)——責任鏈

參考:https://www.jianshu.com/p/e3b6f821acb8html

上文提到java

請求的具體執行在RealCall.getResponseWithInterceptorChain()緩存

private 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 (!retryAndFollowUpInterceptor.isForWebSocket()) {
      interceptors.addAll(client.networkInterceptors());
    }
  //負責向服務器發送數據和從服務器獲取數據的攔截器 interceptors.add(new CallServerInterceptor(retryAndFollowUpInterceptor.isForWebSocket())); Interceptor.Chain chain = new RealInterceptorChain( interceptors, null, null, null, 0, originalRequest); return chain.proceed(originalRequest); }

  

一.攔截器模式的實現

  責任鏈構造器服務器

public RealInterceptorChain(List<Interceptor> interceptors, StreamAllocation streamAllocation,
      HttpStream httpStream, Connection connection, int index, Request request) {
    this.interceptors = interceptors;
    this.connection = connection;
    this.streamAllocation = streamAllocation;
    this.httpStream = httpStream;
    this.index = index;
    this.request = request;
  }

  

public Response proceed(Request request, StreamAllocation streamAllocation, HttpStream httpStream,
      Connection connection) throws IOException {
    //省略一部分
      // Call the next interceptor in the chain.    

    RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpStream, connection, index + 1, request);
    Interceptor interceptor = interceptors.get(index);
    Response response = interceptor.intercept(next);

}

  咱們看到proceed()就是執行攔截器集合的第index個攔截器,同時intercept方法的參數又是攔截器鏈,可是該攔截器鏈不用this而從新構造一個新的在於構造器參數index設爲了index+1cookie

  咱們假設用戶沒有自定義攔截器,則第一個攔截器爲RetryAndFollowUpInterceptor。ide

  

@Override public Response intercept(Chain chain) throws IOException {
  //省略一部分
  
Response response = null;
boolean releaseConnection = true;
try {
response = ((RealInterceptorChain) chain).proceed(request, streamAllocation, null, null);
releaseConnection = false;
} catch (RouteException e) {
  //省略
}

  咱們看到該攔截器的intercepte方法又是執行攔截器鏈的proceed方法,至關於就是執行第index個攔截器,相對本攔截器就是下一個攔截器,同時在proceed方法構造責任器鏈時index又+1了,爲了下下個攔截器作準備。以此類推達到責任鏈模式。ui

  圖示:this

  

 

 

 

  PS

  咱們看着這攔截器模式有點像Android事件分發機制,例如點擊時間在控件上的傳遞,可是有點不同的是事件分發機制在事件分發的過程當中,不管怎麼分發,處理者只能爲一個,可是攔截器在分發後處理返回回來,自生能夠在結果的基礎上在作一層處理。3d

相關文章
相關標籤/搜索