OkHttp 请求流程

OkHttp 请求流程

[toc]

OkHttpClient OkHttpClient.Builder

OKHttp的使用先要初始化OkHttpClient

OkHttpClient 实现了Call.Factory 实现了newCall方法,调用newCall产生一个Call,调用Call的execute或者enqueue方法去发送请求接收响应

OkHttpClient 有两个构造方法

  • 无参构造
public OkHttpClient() {
    //调用了有参数的构造方法
    this(new Builder());
}
  • 有参构造
  OkHttpClient(Builder builder) {

    //用builder中的字段进行初始化
    this.dispatcher = builder.dispatcher;
    this.proxy = builder.proxy;
    this.protocols = builder.protocols;
    this.connectionSpecs = builder.connectionSpecs;
    this.interceptors = Util.immutableList(builder.interceptors);
    this.networkInterceptors = Util.immutableList(builder.networkInterceptors);
    this.eventListenerFactory = builder.eventListenerFactory;
    this.proxySelector = builder.proxySelector;
    this.cookieJar = builder.cookieJar;
    this.cache = builder.cache;
    this.internalCache = builder.internalCache;
    this.socketFactory = builder.socketFactory;

    //根据connectionSpecs判断是否TLS
    boolean isTLS = false;
    for (ConnectionSpec spec : connectionSpecs) {
      isTLS = isTLS || spec.isTls();
    }

    //如果设置了sslSocketFactory或者密码套件不是TLS,设置sslSocketFactory
    //否则用平台默认的信任管理初始化sslSocketFactory
    //也就是说你设置了sslSocketFactory会使用你设置的
    if (builder.sslSocketFactory != null || !isTLS) {
      this.sslSocketFactory = builder.sslSocketFactory;
      this.certificateChainCleaner = builder.certificateChainCleaner;
    } else {
      X509TrustManager trustManager = Util.platformTrustManager();
      this.sslSocketFactory = newSslSocketFactory(trustManager);
      this.certificateChainCleaner = CertificateChainCleaner.get(trustManager);
    }

    //如果你设置sslSocketFactory 或者设置了 tls的密码套件 则sslSocketFactory肯定不为null
    if (sslSocketFactory != null) {
      Platform.get().configureSslSocketFactory(sslSocketFactory);
    }

    //接下来主机验证证书绑定授权代理授权超时时间是否重试等初始化
    this.hostnameVerifier = builder.hostnameVerifier;
    this.certificatePinner = builder.certificatePinner.withCertificateChainCleaner(
        certificateChainCleaner);
    this.proxyAuthenticator = builder.proxyAuthenticator;
    this.authenticator = builder.authenticator;
    this.connectionPool = builder.connectionPool;
    this.dns = builder.dns;
    this.followSslRedirects = builder.followSslRedirects;
    this.followRedirects = builder.followRedirects;
    this.retryOnConnectionFailure = builder.retryOnConnectionFailure;
    this.callTimeout = builder.callTimeout;
    this.connectTimeout = builder.connectTimeout;
    this.readTimeout = builder.readTimeout;
    this.writeTimeout = builder.writeTimeout;
    this.pingInterval = builder.pingInterval;

    if (interceptors.contains(null)) {
      throw new IllegalStateException("Null interceptor: " + interceptors);
    }
    if (networkInterceptors.contains(null)) {
      throw new IllegalStateException("Null network interceptor: " + networkInterceptors);
    }
}

接下来看OkHttpClient.Builder

OkHttpClient.Builder也是提供2个构造函数,一个无参构造提供默认值,一个OkHttpClient 用他的字段来初始化一个新的OkHttpClient

我们看下默认的

public Builder() {
    //新建一个分发器
      dispatcher = new Dispatcher();
      //默认的协议 http2 和http 1.1
      protocols = DEFAULT_PROTOCOLS;
      //默认的密码套件,一个tls安全的,一个不安全的
      connectionSpecs = DEFAULT_CONNECTION_SPECS;
      //默认的事件监听器,空实现
      eventListenerFactory = EventListener.factory(EventListener.NONE);
      proxySelector = ProxySelector.getDefault();
      if (proxySelector == null) {
        proxySelector = new NullProxySelector();
      }
      //默认不处理cookie
      cookieJar = CookieJar.NO_COOKIES;
      //DefaultSocketFactory
      socketFactory = SocketFactory.getDefault();
      //默认的主机验证OkHostnameVerifier,一个恶汉式单例
      hostnameVerifier = OkHostnameVerifier.INSTANCE;
      //默认的证书绑定是空的
      certificatePinner = CertificatePinner.DEFAULT;
      //默认的授权返回是null,并未处理
      proxyAuthenticator = Authenticator.NONE;
      authenticator = Authenticator.NONE;
      //默认参数的连接池
      connectionPool = new ConnectionPool();
      //java默认的dns api InetAddress.getAllByName(hostname)
      dns = Dns.SYSTEM;
      //重试重定向的设置
      followSslRedirects = true;
      followRedirects = true;
      retryOnConnectionFailure = true;
      //超时时间
      callTimeout = 0;
      connectTimeout = 10_000;
      readTimeout = 10_000;
      writeTimeout = 10_000;
      pingInterval = 0;
    }

Request

OkHttpClient的newCall方法需要一个Request参数,我们看看Request

public final class Request {
    //url
  final HttpUrl url;
  //post get等请求方法
  final String method;
  //http请求的headers
  final Headers headers;
  //请求体
  final @Nullable RequestBody body;
  final Map<Class<?>, Object> tags;
    //缓存控制
  private volatile @Nullable CacheControl cacheControl; // Lazily initialized.

//只提供了一个带参数的构造
  Request(Builder builder) {
    this.url = builder.url;
    this.method = builder.method;
    this.headers = builder.headers.build();
    this.body = builder.body;
    this.tags = Util.immutableMap(builder.tags);
  }
}

从上面可以看到Request的主要字段和一个构造方法,我们看下Builder

public static class Builder {
    @Nullable HttpUrl url;
    String method;
    Headers.Builder headers;
    @Nullable RequestBody body;

    /** A mutable map of tags, or an immutable empty map if we don't have any. */
    Map<Class<?>, Object> tags = Collections.emptyMap();

    public Builder() {
        //默认为get
      this.method = "GET";
      this.headers = new Headers.Builder();
    }

    Builder(Request request) {
      this.url = request.url;
      this.method = request.method;
      this.body = request.body;
      this.tags = request.tags.isEmpty()
          ? Collections.emptyMap()
          : new LinkedHashMap<>(request.tags);
      this.headers = request.headers.newBuilder();
    }

    public Builder url(String url) {
      if (url == null) throw new NullPointerException("url == null");
        //将websocket的请求替换为http 和https的方式
      // Silently replace web socket URLs with HTTP URLs.
      if (url.regionMatches(true, 0, "ws:", 0, 3)) {
        url = "http:" + url.substring(3);
      } else if (url.regionMatches(true, 0, "wss:", 0, 4)) {
        url = "https:" + url.substring(4);
      }
        //通过HttpUrl解析方法生成HttpUrl
      return url(HttpUrl.get(url));
    }

    //添加name-value header的2中方式

    //第一种header方法会清除了headers中的同name的值,然后添加该name 和 value
    public Builder header(String name, String value) {
      headers.set(name, value);
      return this;
    }

    //直接添加
    public Builder addHeader(String name, String value) {
      headers.add(name, value);
      return this;
    }
    //直接设置一个headers,用这个headers的配置创建一个新的的Headers覆盖之前的
    public Builder headers(Headers headers) {
      this.headers = headers.newBuilder();
      return this;
    }

     //清楚name 等于参数的所有header
    public Builder removeHeader(String name) {
      headers.removeAll(name);
      return this;
    }

    //缓存控制
    public Builder cacheControl(CacheControl cacheControl) {
      String value = cacheControl.toString();
      if (value.isEmpty()) return removeHeader("Cache-Control");
      return header("Cache-Control", value);
    }

    //请求方法get post 等
     public Builder get() {
      return method("GET", null);
    }
    //只有POST DELETE PUT PATCH的请求方法才有RequestBody
    public Builder post(RequestBody body) {
      return method("POST", body);
    }
}

RequestBody

接下来看看RequestBoy

RequestBody是个抽象类

public abstract class RequestBody {

  public abstract @Nullable MediaType contentType();

  public long contentLength() throws IOException {
    return -1;
  }

    //可以看成outputsteam 用来写数据的
  public abstract void writeTo(BufferedSink sink) throws IOException;

  public boolean isDuplex() {
    return false;
  }

  public boolean isOneShot() {
    return false;
  }
}

RequestBody类中提供几个内置的静态实现,用来提交一个文本 字节 或者 file

    //用一个String 和 MediaType 来创建一个RequestBody,如果MediaType没有指定编码默认是utf8编码
 public static RequestBody create(@Nullable MediaType contentType, String content) {
    Charset charset = UTF_8;
    if (contentType != null) {
      charset = contentType.charset();
      if (charset == null) {
        charset = UTF_8;
        contentType = MediaType.parse(contentType + "; charset=utf-8");
      }
    }
    byte[] bytes = content.getBytes(charset);
    //调用另外一个内置方法
    return create(contentType, bytes);
}
    //MediaType 和一个byte[]数组
  public static RequestBody create(final @Nullable MediaType contentType, final byte[] content) {
    return create(contentType, content, 0, content.length);
  }

  public static RequestBody create(final @Nullable MediaType contentType, final byte[] content,
      final int offset, final int byteCount) {
    if (content == null) throw new NullPointerException("content == null");
    Util.checkOffsetAndCount(content.length, offset, byteCount);
    return new RequestBody() {
      @Override public @Nullable MediaType contentType() {
        return contentType;
      }

      @Override public long contentLength() {
        return byteCount;
      }

      @Override public void writeTo(BufferedSink sink) throws IOException {
        sink.write(content, offset, byteCount);
      }
    };
  }

    //ByteString 是Okio的类,提供方便的hex形式的字符串和byte[]
  public static RequestBody create(
      final @Nullable MediaType contentType, final ByteString content) {
    return new RequestBody() {
      @Override public @Nullable MediaType contentType() {
        return contentType;
      }

      @Override public long contentLength() throws IOException {
        return content.size();
      }

      @Override public void writeTo(BufferedSink sink) throws IOException {
        sink.write(content);
      }
    };
  }
    //用一个file 和MediaType 创建 RequestBody
    public static RequestBody create(final @Nullable MediaType contentType, final File file) {
    if (file == null) throw new NullPointerException("file == null");

    return new RequestBody() {
      @Override public @Nullable MediaType contentType() {
        return contentType;
      }

      @Override public long contentLength() {
        return file.length();
      }

      @Override public void writeTo(BufferedSink sink) throws IOException {
          //source 可以看成inputstream
        try (Source source = Okio.source(file)) {
          sink.writeAll(source);
        }
      }
    };
  }

RequestBody有两个子类FormBody MultipartBody

FormBody 表单形式的请求体

FormBody 是一个代表表单形式的请求体,name - value形式

重写了writeTo方法
将表单用utf8的编码拼接写入io流

 @Override public void writeTo(BufferedSink sink) throws IOException {
    writeOrCountBytes(sink, false);
  }

  private long writeOrCountBytes(@Nullable BufferedSink sink, boolean countBytes) {
    long byteCount = 0L;

    Buffer buffer;
    if (countBytes) {
      buffer = new Buffer();
    } else {
      buffer = sink.buffer();
    }

    for (int i = 0, size = encodedNames.size(); i < size; i++) {
      if (i > 0) buffer.writeByte('&');
      buffer.writeUtf8(encodedNames.get(i));
      buffer.writeByte('=');
      buffer.writeUtf8(encodedValues.get(i));
    }

    if (countBytes) {
      byteCount = buffer.size();
      buffer.clear();
    }

    return byteCount;
  }

MultipartBody

复杂类型的请求体

可以通过builder来初始化

public static final class Builder {
    //分隔符
    private final ByteString boundary;
    private MediaType type = MIXED;
    private final List<Part> parts = new ArrayList<>();

    public Builder() {
      this(UUID.randomUUID().toString());
    }

    public Builder(String boundary) {
      this.boundary = ByteString.encodeUtf8(boundary);
    }

    //设置MediaType type必须是multipart 例如 multipart/mixed multipart/form-data 等等形式
    public Builder setType(MediaType type) {
      if (type == null) {
        throw new NullPointerException("type == null");
      }
      if (!type.type().equals("multipart")) {
        throw new IllegalArgumentException("multipart != " + type);
      }
      this.type = type;
      return this;
    }

    /** Add a part to the body. */
    public Builder addPart(RequestBody body) {
      return addPart(Part.create(body));
    }

    /** Add a part to the body. */
    public Builder addPart(@Nullable Headers headers, RequestBody body) {
      return addPart(Part.create(headers, body));
    }

    /** Add a form data part to the body. */
    public Builder addFormDataPart(String name, String value) {
      return addPart(Part.createFormData(name, value));
    }

    /** Add a form data part to the body. */
    public Builder addFormDataPart(String name, @Nullable String filename, RequestBody body) {
      return addPart(Part.createFormData(name, filename, body));
    }

    /** Add a part to the body. */
    public Builder addPart(Part part) {
      if (part == null) throw new NullPointerException("part == null");
      parts.add(part);
      return this;
    }
}

Builder方法主要是addPart 和 addFromPart

我们看下Part,就一个Headers 一个RequestBody

public static final class Part {
    final @Nullable Headers headers;
    final RequestBody body;

    private Part(@Nullable Headers headers, RequestBody body) {
      this.headers = headers;
      this.body = body;
    }

    public @Nullable Headers headers() {
      return headers;
    }

    public RequestBody body() {
      return body;
    }
}

我们来看addPart

public static Part create(RequestBody body) {
      return create(null, body);
    }

    public static Part create(@Nullable Headers headers, RequestBody body) {
        //body是肯定不能为null的
      if (body == null) {
        throw new NullPointerException("body == null");
      }
      //如果有header Content-Type Content-Length 必须有
      if (headers != null && headers.get("Content-Type") != null) {
        throw new IllegalArgumentException("Unexpected header: Content-Type");
      }
      if (headers != null && headers.get("Content-Length") != null) {
        throw new IllegalArgumentException("Unexpected header: Content-Length");
      }
      return new Part(headers, body);
    }

addPart很简单,看下 addFormData

//name - value 形式的表单值调用 的还是调用的下面的三个参数的方法
public static Part createFormData(String name, String value) {
      return createFormData(name, null, RequestBody.create(null, value));
    }

//创建一个带文件名的part,显然,要上传文件的复杂表单类型用这个,RequestBody 可以用内置的静态方法create来创建
public static Part createFormData(String name, @Nullable String filename, RequestBody body) {
    //name 不能为null
      if (name == null) {
        throw new NullPointerException("name == null");
      }
      //描述
      StringBuilder disposition = new StringBuilder("form-data; name=");
      //form-data; name="name" name是经过对一些特殊字符进行编码的形式
      appendQuotedString(disposition, name);

        //如果有文件名就是描述后面加上,完成后形式如下form-data; name="name"; filename="filename"
      if (filename != null) {
        disposition.append("; filename=");
        appendQuotedString(disposition, filename);
      }
        //新建一个Headers 把Content-Disposition添加到Headers中
      Headers headers = new Headers.Builder()
          .addUnsafeNonAscii("Content-Disposition", disposition.toString())
          .build();

      return create(headers, body);
}

MultipartBody同样重写了writeTo方法

@Override public void writeTo(BufferedSink sink) throws IOException {
    writeOrCountBytes(sink, false);
  }

  private long writeOrCountBytes(
      @Nullable BufferedSink sink, boolean countBytes) throws IOException {
    long byteCount = 0L;

    Buffer byteCountBuffer = null;
    if (countBytes) {
      sink = byteCountBuffer = new Buffer();
    }

    //遍历parts
    for (int p = 0, partCount = parts.size(); p < partCount; p++) {
      Part part = parts.get(p);
      Headers headers = part.headers;
      RequestBody body = part.body;
        //每个part的处理
        //写入--分隔符 回车换行  分隔符是UUID.randomUUID().toString() 一个随机的UUID
      sink.write(DASHDASH);
      sink.write(boundary);
      sink.write(CRLF);
        //每个part的headers处理
      if (headers != null) {
          //h相当于headers的索引,headerCount是数量,相当于数组遍历
        for (int h = 0, headerCount = headers.size(); h < headerCount; h++) {
            //写入 name: value 然后回车换行
          sink.writeUtf8(headers.name(h))
              .write(COLONSPACE)
              .writeUtf8(headers.value(h))
              .write(CRLF);
        }
      }
        //写入MediaType
      MediaType contentType = body.contentType();
      if (contentType != null) {
        sink.writeUtf8("Content-Type: ")
            .writeUtf8(contentType.toString())
            .write(CRLF);
      }
    //写入Content-Length
      long contentLength = body.contentLength();
      if (contentLength != -1) {
        sink.writeUtf8("Content-Length: ")
            .writeDecimalLong(contentLength)
            .write(CRLF);
      } else if (countBytes) {
        // We can't measure the body's size without the sizes of its components.
        byteCountBuffer.clear();
        return -1L;
      }

      sink.write(CRLF);

      if (countBytes) {
        byteCount += contentLength;
      } else {
          //写入每个Part的RequestBody
        body.writeTo(sink);
      }
      sink.write(CRLF);
    }

    sink.write(DASHDASH);
    sink.write(boundary);
    sink.write(DASHDASH);
    sink.write(CRLF);

    if (countBytes) {
      byteCount += byteCountBuffer.size();
      byteCountBuffer.clear();
    }

    return byteCount;
  }

Call RealCall

Call是个借口定义了同步请求方法异步请求方法取消请求等,RealCall是Call的实现类

我们看下OkHttpClient的newCall方法

 @Override public Call newCall(Request request) {
    return RealCall.newRealCall(this, request, false /* for web socket */);
  }

RealCall.newRealCall

final class RealCall implements Call {
    private RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
    this.client = client;
    this.originalRequest = originalRequest;
    this.forWebSocket = forWebSocket;
  }

  static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
    // Safely publish the Call instance to the EventListener.
    RealCall call = new RealCall(client, originalRequest, forWebSocket);
    //OkHttp的网络层,连接啥的都是他干的
    call.transmitter = new Transmitter(client, call);
    return call;
  }
}

同步的请求

  @Override public Response execute() throws IOException {
      //不能多次execute
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    //超时计时开始,实际是okio的AsyncTimeout
    transmitter.timeoutEnter();
    //开始调用,在时间监听回调callStart
    transmitter.callStart();
    try {
        //分发器同步调用
      client.dispatcher().executed(this);
      //责任链模式的InterceptorChain,
      return getResponseWithInterceptorChain();
    } finally {
      client.dispatcher().finished(this);
    }
  }

Dispatcher

看下Dispatcher


public final class Dispatcher {
  private int maxRequests = 64;
  private int maxRequestsPerHost = 5;
  private @Nullable Runnable idleCallback;

  /** Executes calls. Created lazily. */
  private @Nullable ExecutorService executorService;

  /** Ready async calls in the order they'll be run. */
  private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>();

  /** Running asynchronous calls. Includes canceled calls that haven't finished yet. */
  private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>();

  /** Running synchronous calls. Includes canceled calls that haven't finished yet. */
  private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();

  public Dispatcher(ExecutorService executorService) {
    this.executorService = executorService;
  }

  public Dispatcher() {
  }

  public synchronized ExecutorService executorService() {
    if (executorService == null) {
      executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
          new SynchronousQueue<>(), Util.threadFactory("OkHttp Dispatcher", false));
    }
    return executorService;
  }

  /** Used by {@code Call#execute} to signal it is in-flight. */
  synchronized void executed(RealCall call) {
      //将RealCall加入了同步的队列中
    runningSyncCalls.add(call);
  }

  /** Used by {@code AsyncCall#run} to signal completion. */
  void finished(AsyncCall call) {
    call.callsPerHost().decrementAndGet();
    finished(runningAsyncCalls, call);
  }

  /** Used by {@code Call#execute} to signal completion. */
  //刚才在readl里面始终会调用这个方法
  void finished(RealCall call) {
    finished(runningSyncCalls, call);
  }

private <T> void finished(Deque<T> calls, T call) {
    Runnable idleCallback;
    synchronized (this) {
      if (!calls.remove(call)) throw new AssertionError("Call wasn't in-flight!");
      idleCallback = this.idleCallback;
    }
    //发起执行
    boolean isRunning = promoteAndExecute();

    if (!isRunning && idleCallback != null) {
      idleCallback.run();
    }
  }
}

//同步异步都会调用它
private boolean promoteAndExecute() {
    assert (!Thread.holdsLock(this));

    List<AsyncCall> executableCalls = new ArrayList<>();
    boolean isRunning;
    synchronized (this) {
        //迭代异步准备队列
      for (Iterator<AsyncCall> i = readyAsyncCalls.iterator(); i.hasNext(); ) {
        AsyncCall asyncCall = i.next();
        //如果当前runningAsyncCalls的数量>= 最大请求数,跳出循环
        if (runningAsyncCalls.size() >= maxRequests) break; // Max capacity.
        //如果当前的主机名的请求已经超过最大的 跳过这次
        if (asyncCall.callsPerHost().get() >= maxRequestsPerHost) continue; // Host max capacity.
        //到这里说明请求没量没超,从异步准备队列删除
        i.remove();
        asyncCall.callsPerHost().incrementAndGet();
        //将AsyncCall 加入executableCalls 和 runningAsyncCalls
        executableCalls.add(asyncCall);
        runningAsyncCalls.add(asyncCall);
      }
      //runningSyncCalls + runningAsyncCalls 的数量大于0 说明有任务运行
      isRunning = runningCallsCount() > 0;
    }

//遍历executableCalls 并在线程池的线程执行
    for (int i = 0, size = executableCalls.size(); i < size; i++) {
      AsyncCall asyncCall = executableCalls.get(i);
      asyncCall.executeOn(executorService());
    }

    return isRunning;
  }

    public synchronized int runningCallsCount() {
    return runningAsyncCalls.size() + runningSyncCalls.size();
  }

看下异步

 @Override public void enqueue(Callback responseCallback) {
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    transmitter.callStart();
    client.dispatcher().enqueue(new AsyncCall(responseCallback));
  }
 void enqueue(AsyncCall call) {
    synchronized (this) {
        //加入准备队列
      readyAsyncCalls.add(call);

      // Mutate the AsyncCall so that it shares the AtomicInteger of an existing running call to
      // the same host.
      if (!call.get().forWebSocket) {
        AsyncCall existingCall = findExistingCallWithHost(call.host());
        if (existingCall != null) call.reuseCallsPerHostFrom(existingCall);
      }
    }
    //调用这个发起执行的方法
    promoteAndExecute();
  }

目前同步的任务加入了runningSyncCalls而 异步的要执行的任务加入了runningAsyncCalls 和 executableCalls 中并调用了AsyncCall的executeOn 传入一个线程池

AsyncCall

AsyncCall是一个NamedRunnable NameRunable 在run方法中调用了execute

 void executeOn(ExecutorService executorService) {
      assert (!Thread.holdsLock(client.dispatcher()));
      boolean success = false;
      try {
          //在线程池执行run方法,在run方法调用了execute
        executorService.execute(this);
        success = true;
      } catch (RejectedExecutionException e) {
          //线程池满了发生异常就callback失败
        InterruptedIOException ioException = new InterruptedIOException("executor rejected");
        ioException.initCause(e);
        transmitter.noMoreExchanges(ioException);
        responseCallback.onFailure(RealCall.this, ioException);
      } finally {
        if (!success) {
            //发生异常调用完成
          client.dispatcher().finished(this); // This call is no longer running!
        }
      }
    }

    @Override protected void execute() {
      boolean signalledCallback = false;
      //超时计时开始
      transmitter.timeoutEnter();
      try {
          //在这个方法添加自己定义的拦截器和内置的拦截器采用责任链模式链式调用返回Response
        Response response = getResponseWithInterceptorChain();
        signalledCallback = true;
        responseCallback.onResponse(RealCall.this, response);
      } catch (IOException e) {
        if (signalledCallback) {
          // Do not signal the callback twice!
          Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
        } else {
          responseCallback.onFailure(RealCall.this, e);
        }
      } finally {
        client.dispatcher().finished(this);
      }
    }

看到这里发现不管同步异步都到了getResponseWithInterceptorChain这个方法

 Response getResponseWithInterceptorChain() throws IOException {
    // Build a full stack of interceptors.
    List<Interceptor> interceptors = new ArrayList<>();
    //添加我们在OkhttpClient中设置的拦截器
    interceptors.addAll(client.interceptors());
    
    //添加内置的拦截器
    interceptors.add(new RetryAndFollowUpInterceptor(client));//重试重定向拦截器
    interceptors.add(new BridgeInterceptor(client.cookieJar()));//处理一些通用的header
    interceptors.add(new CacheInterceptor(client.internalCache()));//处理缓存的拦截器
    interceptors.add(new ConnectInterceptor(client));//创建了Socket 和 安全的Socket
    if (!forWebSocket) {
        //添加我们在OkHttpClient中添加的网络拦截器
      interceptors.addAll(client.networkInterceptors());
    }
    //最后添加正在调用的拦截器
    interceptors.add(new CallServerInterceptor(forWebSocket));

//new  RealInterceptorChain 传入了Interceptor集合 下标0,超时时间,request等
    Interceptor.Chain chain = new RealInterceptorChain(interceptors, transmitter, null, 0,
        originalRequest, this, client.connectTimeoutMillis(),
        client.readTimeoutMillis(), client.writeTimeoutMillis());

    boolean calledNoMoreExchanges = false;
    try {
        //重点
      Response response = chain.proceed(originalRequest);
      if (transmitter.isCanceled()) {
        closeQuietly(response);
        throw new IOException("Canceled");
      }
      return response;
    } catch (IOException e) {
      calledNoMoreExchanges = true;
      throw transmitter.noMoreExchanges(e);
    } finally {
      if (!calledNoMoreExchanges) {
        transmitter.noMoreExchanges(null);
      }
    }
  }
    private int calls;
 public RealInterceptorChain(List<Interceptor> interceptors, Transmitter transmitter,
      @Nullable Exchange exchange, int index, Request request, Call call,
      int connectTimeout, int readTimeout, int writeTimeout) {
    this.interceptors = interceptors;
    this.transmitter = transmitter;
    this.exchange = exchange;
    this.index = index;
    this.request = request;
    this.call = call;
    this.connectTimeout = connectTimeout;
    this.readTimeout = readTimeout;
    this.writeTimeout = writeTimeout;
  }


  @Override public Response proceed(Request request) throws IOException {
    return proceed(request, transmitter, exchange);
  }

  public Response proceed(Request request, Transmitter transmitter, @Nullable Exchange exchange)
      throws IOException {
    if (index >= interceptors.size()) throw new AssertionError();

    calls++;//初始化0 ++ 后1

    // If we already have a stream, confirm that the incoming request will use it.
    if (this.exchange != null && !this.exchange.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.exchange != null && calls > 1) {
      throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
          + " must call proceed() exactly once");
    }

    //这这里new RealInterceptorChain,把拦截器集合和当前索引+1传进去
    // Call the next interceptor in the chain.
    RealInterceptorChain next = new RealInterceptorChain(interceptors, transmitter, exchange,
        index + 1, request, call, connectTimeout, readTimeout, writeTimeout);
        //获取当前索引的拦截器,那刚才其实就是下一个索引的拦截器
    Interceptor interceptor = interceptors.get(index);
    //调用拦截器的intercept,Chain 是下一个索引的RealInterceptorChain
    //也就是说只要interceptor.intercept方法中调用了Chain.proceed,那么有调回了下一个索引的这个方法,依次直到最后一个然后返回,典型的责任链模式
    Response response = interceptor.intercept(next);

    // Confirm that the next interceptor made its required call to chain.proceed().
    if (exchange != 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;
  }

其实到这里还没有真正的去请求,接下来要看内置的拦截器

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容