Okhttp的浅层架构分析

Okhttp的浅层架构分析
Okhttp的责任链模式和拦截器分析
Okhttp之RetryAndFollowUpInterceptor拦截器分析
Okhttp之BridgeInterceptor拦截器分析
Okhttp之CacheInterceptor拦截器分析
Okhttp之ConnectInterceptor拦截器分析
Okhttp之网络连接相关三大类RealConnection、ConnectionPool、StreamAllocation
Okhttp之CallServerInterceptor拦截器分析
浅析okio的架构和源码实现

Okhttp作为现在最受欢迎的网络框架,没有之一,为什么会这么有说服力的让开发者们都认可呢,带着这些疑问我们看看它的源码是怎么设计的。

首先看看okhttp的异步Get请求:

        //bulider模式创建一个默认的OkhttpClient对象
        var client = OkHttpClient.Builder().build()
        //仍然是builder模式创建Request对象
        var request = Request.Builder().url("https://www.baidu.com").get().build()
        //调用OkHttpClient的newCall()方法新建了一个RealCall对象
        val newCall = client.newCall(request)
        //调用RealCall的enqueue()方法开启异步线程访问,传入回调接口
        newCall.enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
            }

            override fun onResponse(call: Call, response: Response) {
            }
        })

我们就一步步跟着看看它每一个步骤都是怎么实现的,先看看OkHttpClient的主要代码,这里就只先关注以上步骤出现的相关代码,先把流程梳理清楚,所以就看看它的Builder内部类:

  public static final class Builder {
    Dispatcher dispatcher; //异步调用分配者,通过线程池,来分别调用
    @Nullable Proxy proxy;
    List protocols;
    List connectionSpecs;
    final List interceptors = new ArrayList<>();// 自定义拦截器 集合
    final List networkInterceptors = new ArrayList<>(); //网络拦截器 集合
    EventListener.Factory eventListenerFactory;
    ProxySelector proxySelector;
    CookieJar cookieJar;    //cookie
    @Nullable Cache cache; //缓存
    @Nullable InternalCache internalCache;
    SocketFactory socketFactory;
    @Nullable SSLSocketFactory sslSocketFactory;
    @Nullable CertificateChainCleaner certificateChainCleaner;
    HostnameVerifier hostnameVerifier;
    CertificatePinner certificatePinner;
    Authenticator proxyAuthenticator;
    Authenticator authenticator;
    ConnectionPool connectionPool; //线程池,所有的有效链接都会保存在这里,也优先在这里查找是否有可用的链接
    Dns dns;
    boolean followSslRedirects;
    boolean followRedirects;
    boolean retryOnConnectionFailure;
    //各种超时时间设置,看名字就知道是干啥的啦
    int callTimeout; 
    int connectTimeout;
    int readTimeout;
    int writeTimeout;
    int pingInterval;

  public Builder() {
      dispatcher = new Dispatcher();
      protocols = DEFAULT_PROTOCOLS;
      connectionSpecs = DEFAULT_CONNECTION_SPECS;
      eventListenerFactory = EventListener.factory(EventListener.NONE);
      proxySelector = ProxySelector.getDefault();
      if (proxySelector == null) {
        proxySelector = new NullProxySelector();
      }
      cookieJar = CookieJar.NO_COOKIES;
      socketFactory = SocketFactory.getDefault();
      hostnameVerifier = OkHostnameVerifier.INSTANCE;
      certificatePinner = CertificatePinner.DEFAULT;
      proxyAuthenticator = Authenticator.NONE;
      authenticator = Authenticator.NONE;
      connectionPool = new ConnectionPool();
      dns = Dns.SYSTEM;
      followSslRedirects = true;
      followRedirects = true;
      retryOnConnectionFailure = true;
      callTimeout = 0;
      connectTimeout = 10_000;
      readTimeout = 10_000;
      writeTimeout = 10_000;
      pingInterval = 0;
    }

    ...省略其他代码
}

主要的一些属性都注释了,其他的暂时不深究,这里默认初始化的时候重点关注Dispatcher类,到时候会用到它。接下来看看newCall()方法:

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

来看看RealCall类

final class RealCall implements Call {
  final OkHttpClient client;
  final RetryAndFollowUpInterceptor retryAndFollowUpInterceptor;
  final AsyncTimeout timeout;

//静态方法,传入了client,request等参数
static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
    // Safely publish the Call instance to the EventListener.
    RealCall call = new RealCall(client, originalRequest, forWebSocket);
    call.eventListener = client.eventListenerFactory().create(call);
    return call;
  }
   @Override 
  public void enqueue(Callback responseCallback) {
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    captureCallStackTrace();
    eventListener.callStart(this);
    //OkhttpClient里的那个成员变量dispatcher
    client.dispatcher().enqueue(new AsyncCall(responseCallback));
  }
}

我们知道okhttp的异步请求是调用了enqueue()方法,在这个方法里我们看到了之前提到的OkhttpClient里的那个成员变量dispatcher,最终是调用了它的enqueue()方法,那我们来看看Dispatcher的enqueue()方法:

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

//熟悉的线程池
  private @Nullable ExecutorService executorService;
  //准备好的要执行的任务
  private final Deque readyAsyncCalls = new ArrayDeque<>();


 void enqueue(AsyncCall call) {
    synchronized (this) {
      readyAsyncCalls.add(call);
    }
    promoteAndExecute();
  }
}

  private boolean promoteAndExecute() {
    assert (!Thread.holdsLock(this));

    List executableCalls = new ArrayList<>();
    boolean isRunning;
  //准备可执行的任务
    synchronized (this) {
      for (Iterator i = readyAsyncCalls.iterator(); i.hasNext(); ) {
        AsyncCall asyncCall = i.next();
        if (runningAsyncCalls.size() >= maxRequests) break; // Max capacity.
        if (runningCallsForHost(asyncCall) >= maxRequestsPerHost) continue; // Host max capacity.
        i.remove();
        executableCalls.add(asyncCall);
        runningAsyncCalls.add(asyncCall);
      }
      isRunning = runningCallsCount() > 0;
    }
  //遍历执行可执行的任务
    for (int i = 0, size = executableCalls.size(); i < size; i++) {
      AsyncCall asyncCall = executableCalls.get(i);
      //放到线程池里去执行,这个executeOn()是asyncCall的方法,executorService()方法就是得到一个线程池,AsyncCall类,这个类肯定是个ruannable
      asyncCall.executeOn(executorService());
    }
    return isRunning;
  }
  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;
  }
  

AsyncCall类,前面提到这个类肯定是个ruannable,看看源码:

//带名称的Runnable ,方便管理标记,AsyncCall继承了这个类
public abstract class NamedRunnable implements Runnable {
  protected final String name;

  public NamedRunnable(String format, Object... args) {
    this.name = Util.format(format, args);
  }

  @Override public final void run() {
    String oldName = Thread.currentThread().getName();
    Thread.currentThread().setName(name);
    try {
      //子类实现,最终的执行代码放在这里
      execute();
    } finally {
      Thread.currentThread().setName(oldName);
    }
  }

  protected abstract void execute();
}

//AsyncCall,实现的了NamedRunnable 
  final class AsyncCall extends NamedRunnable {
    private final Callback responseCallback;

    AsyncCall(Callback responseCallback) {
      super("OkHttp %s", redactedUrl());
      this.responseCallback = responseCallback;
    }
//上面dispatcher调用的方法
void executeOn(ExecutorService executorService) {
      assert (!Thread.holdsLock(client.dispatcher()));
      boolean success = false;
      try {
        //最终的执行步骤,线程池的execute()方法,注意executorService是执行了AsyncCall ,也就是会执行下面的execute() 方法,不要晕
        executorService.execute(this);
        success = true;
      } catch (RejectedExecutionException e) {
        InterruptedIOException ioException = new InterruptedIOException("executor rejected");
        ioException.initCause(e);
        eventListener.callFailed(RealCall.this, ioException);
        responseCallback.onFailure(RealCall.this, ioException);
      } finally {
        if (!success) {
          client.dispatcher().finished(this); // This call is no longer running!
        }
      }
    }
     //最终的请求提交,可以看到getResponseWithInterceptorChain()方法拿到response ,这就是开始了责任链调用模式,后面详细分析
    @Override
   protected void execute() {
      boolean signalledCallback = false;
      timeout.enter();
      try {
       //开启责任链调用拿到response
        Response response = getResponseWithInterceptorChain();
        if (retryAndFollowUpInterceptor.isCanceled()) {
          signalledCallback = true;
          responseCallback.onFailure(RealCall.this, new IOException("Canceled"));
        } else {
          signalledCallback = true;
          responseCallback.onResponse(RealCall.this, response);
        }
      } catch (IOException e) {
        e = timeoutExit(e);
        if (signalledCallback) {
          // Do not signal the callback twice!
          Platform.get().log(INFO, "Callback failure for " + toLoggableString(), e);
        } else {
          eventListener.callFailed(RealCall.this, e);
          responseCallback.onFailure(RealCall.this, e);
        }
      } finally {
        client.dispatcher().finished(this);
      }
    }
  }

至此,okhttp的大致异步调用的大概结构了解了,说到底还是把请求任务封装成runnable放在线程池里去执行,当然这只是整体脉络,要继续了解它是怎么得到response响应的,就要开始聊聊它著名的责任链模式和拦截器的设计了,篇幅有限我们放到下篇来讲。

你可能感兴趣的:(Okhttp的浅层架构分析)