美文网首页
OkHttp3(九)--RealInterceptorChain

OkHttp3(九)--RealInterceptorChain

作者: azu_test | 来源:发表于2019-01-28 14:33 被阅读0次

    RealInterceptorChain

    • 拦截器链表存储器,里面存储了所有的拦截器,还有一些网络请求属性
    • 每次执行下一个拦截器的拦截事件前都会创建一个新的拦截器链表,用来更新为最新的数据,然后将拦截器链表交付给拦截器,让拦截器去做新的拦截操作,最后返回请求数据。
    • 至于怎么让拦截器执行下一个拦截操作使用的是private final int index;这个属性值来做鉴别应该取拦截器链表里面的第几个拦截器,然后让其做相应的拦截操作。

    RealInterceptorChain关键代码

    public final class RealInterceptorChain implements Interceptor.Chain {
      //所有的拦截器都存储在这个链表里
      private final List<Interceptor> interceptors;
      //这个非常重要,将会单独解读处理
      private final StreamAllocation streamAllocation;
      //这个非常重要,将会单独解读处理
      private final HttpCodec httpCodec;
      //这个非常重要,将会单独解读处理
      private final RealConnection connection;
      private final int index;
      private final Request request;
      private final Call call;
      private final EventListener eventListener;
      private final int connectTimeout;
      private final int readTimeout;
      private final int writeTimeout;
      private int calls;
      //构造方法
      public RealInterceptorChain(List<Interceptor> interceptors, StreamAllocation streamAllocation,
          HttpCodec httpCodec, RealConnection connection, int index, Request request, Call call,
          EventListener eventListener, int connectTimeout, int readTimeout, int writeTimeout) {
        this.interceptors = interceptors;
        this.connection = connection;
        this.streamAllocation = streamAllocation;
        this.httpCodec = httpCodec;
        this.index = index;
        this.request = request;
        this.call = call;
        this.eventListener = eventListener;
        this.connectTimeout = connectTimeout;
        this.readTimeout = readTimeout;
        this.writeTimeout = writeTimeout;
      }
      //执行继续拦截操作
      @Override public Response proceed(Request request) throws IOException {
        return proceed(request, streamAllocation, httpCodec, connection);
      }
      //执行继续拦截操作
      public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,
          RealConnection connection) throws IOException {
        if (index >= interceptors.size()) throw new AssertionError();
    
        calls++;
    
        // If we already have a stream, confirm that the incoming request will use it.
        if (this.httpCodec != null && !this.connection.supportsUrl(request.url())) {
          throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
              + " must retain the same host and port");
        }
    
        // If we already have a stream, confirm that this is the only call to chain.proceed().
        if (this.httpCodec != null && calls > 1) {
          throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
              + " must call proceed() exactly once");
        }
    
        //创建新的实例, 并将计数器+1
        RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec,
            connection, index + 1, request, call, eventListener, connectTimeout, readTimeout,
            writeTimeout);
        //取出下一个拦截器
        Interceptor interceptor = interceptors.get(index);
        //执行拦截器方法,拦截器中又会调用proceed()方法
        Response response = interceptor.intercept(next);
        // Confirm that the next interceptor made its required call to chain.proceed().
        if (httpCodec != null && index + 1 < interceptors.size() && next.calls != 1) {
          throw new IllegalStateException("network interceptor " + interceptor
              + " must call proceed() exactly once");
        }
        // Confirm that the intercepted response isn't null.
        if (response == null) {
          throw new NullPointerException("interceptor " + interceptor + " returned null");
        }
        if (response.body() == null) {
          throw new IllegalStateException(
              "interceptor " + interceptor + " returned a response with no body");
        }
        return response;
      }
    }
    
    • 上面代码中有我们实例化的接口,但是里面有一些属性在我们开始进来前没有做赋值处理,给的是空值。
    • 通过调用继续拦截操作proceed()方法将调用拦截器的Interceptor.intercept()方法,然后这个方法内部会根据条件抛出异常、结果或者继续调用proceed()方法进行下一项拦截。
    • 拦截器的顺序RetryAndFollowUpInterceptor,BridgeInterceptor
      CacheInterceptorConnectInterceptorCallServerInterceptor
    • 还有一些属性对象我们目前不知为什么作用,例如:StreamAllocation,HttpCodec,RealConnection。我们将根据代码运行流程一步步来解析。

    根据上文的方法调用和拦截器的顺序我们可知下面将执行RetryAndFollowUpInterceptor拦截器。

    下篇入口:OkHttp3(十)--RetryAndFollowUpInterceptor

    相关文章

      网友评论

          本文标题:OkHttp3(九)--RealInterceptorChain

          本文链接:https://www.haomeiwen.com/subject/hkyajqtx.html