NetAndroid进阶之路Android知识

浅析 OkHttp 的拦截器机制

2017-04-22  本文已影响620人  RunAlgorithm

1 概述

AOP 编程。每次的 proceed 是执行点,可以在执行点的前面和后面添加需要的业务逻辑。比如打打日志,失败重试,添加缓存等等

拦截器就是基于责任链模式,每个节点有自己的职责,同时可以选择是否把任务传递给下一个环节

拦截器的设计,可以像工厂流水线一样,传递用户发起的请求 Request,每一个拦截器完成相应的功能,从失败重试和重定向实现、请求头的修改和Cookie 的处理,缓存的处理,建立 TCP 和 SSH 连接,发送 Request 和读取 Response,每一个环节由专门的 Interceptor 负责

2 类和接口

2.1 Inteceptor

主要方法 Intercept。会传递一个 Chain 对象过来,可以在 Chain 在执行 proceed 的前后添加代码

2.2 Chain

主要方法 proceed。OkHttp 的唯一实现类是 RealInterceptorChain。内部维护了所有要执行的拦截器列表,在 proceed 内部会唤醒下一个 Interceptor ,调用 intercept 来进行下一步

public Response proceed(Request request, StreamAllocation streamAllocation, HttpStream httpStream,
    Connection connection) throws IOException {
  ...
  RealInterceptorChain next = new RealInterceptorChain(
      interceptors, streamAllocation, httpStream, connection, index + 1, request);
  Interceptor interceptor = interceptors.get(index);
  Response response = interceptor.intercept(next);
  ...
  return response;
}

该类的主要成员有

RealInterceptorChain 对 proceed 进行了扩展,在拦截器链式传递的过程中增加了这些对象的传递。所以执行拦截器的时候,启动下一个拦截器的前,可以对这些对象进行创建或者修改,然后再传递给下一个拦截器,或者调用这些对象完成相应的功能。比如在 RetryAndFollowUpInterceptor 会创建 StreamAllocation,在 BridgeInterceptor 会修改 Request 的请求头,在 ConnectInterceptor 会调用 StreamAllocation 的 newStream 方法建立连接等等。

3 基本流程

Call 抽象了一次请求,唯一实现类为 RealCall

当我们调用 call.execute 发起请求后,整个请求的流程发生在下面的方法中

  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);
  }

通过一系列拦截器进行链式操作,一环接一环,每个拦截器负责单独的任务,环环相扣完成整个请求

img_ok_interceptors.png
上一篇 下一篇

猜你喜欢

热点阅读