OkHttp源码--发送请求

OkHttpClient

一般可以通过以下两种方式创建OkhttpClient

OkHttpClient client = new OkHttpClient();
OkHttpClient client = new OkHttpClient.Builder().build();

看一下OkHttpClient构造方法的源码

  public OkHttpClient() {
    // new Builder()也是做了一些初始化配置
    this(new Builder());
  }
  // 主要利用传入的Builder对象初始了OkHttpClient的成员,还有一些初始化工作
  OkHttpClient(Builder builder) {
    this.dispatcher = builder.dispatcher;
    this.proxy = builder.proxy;
    this.protocols = builder.protocols;
    this.connectionSpecs = builder.connectionSpecs;// OkHttp连接配置
    this.interceptors = Util.immutableList(builder.interceptors);
    this.networkInterceptors = Util.immutableList(builder.networkInterceptors);
    this.eventListenerFactory = builder.eventListenerFactory;// 一个Call的状态监听器
    this.proxySelector = builder.proxySelector;
    this.cookieJar = builder.cookieJar;// 默认是没有Cookie的
    this.cache = builder.cache;
    this.internalCache = builder.internalCache;
    this.socketFactory = builder.socketFactory;

    boolean isTLS = false;
    for (ConnectionSpec spec : connectionSpecs) {
      isTLS = isTLS || spec.isTls();
    }

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

    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; // 这个就和WebSocket有关了。为了保持长连接,我们必须间隔一段时间发送一个ping指令进行保活

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

OkHttpClient的静态内部类Builder

主要工作就是封装了外部类需要的参数,并提供了一种比较方便的链式调用方法初始化一个类的成员变量,最后传给外部类完成初始化得到外部对象。

public static final class Builder {
    Dispatcher dispatcher;
    @Nullable Proxy proxy;
    List<Protocol> protocols;
    List<ConnectionSpec> connectionSpecs;
    final List<Interceptor> interceptors = new ArrayList<>();
    final List<Interceptor> networkInterceptors = new ArrayList<>();
    EventListener.Factory eventListenerFactory;
    ProxySelector proxySelector;
    CookieJar cookieJar;
    ...

    // 对成员变量赋初值
    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();
      ...
    }

    // 使用OkHttpClient对成员变量赋值
    Builder(OkHttpClient okHttpClient) {
      this.dispatcher = okHttpClient.dispatcher;
      this.proxy = okHttpClient.proxy;
      this.protocols = okHttpClient.protocols;
      this.connectionSpecs = okHttpClient.connectionSpecs;
      this.interceptors.addAll(okHttpClient.interceptors);
      this.networkInterceptors.addAll(okHttpClient.networkInterceptors);
      this.eventListenerFactory = okHttpClient.eventListenerFactory;
      this.proxySelector = okHttpClient.proxySelector;
      this.cookieJar = okHttpClient.cookieJar;
      ...
    }
    
    // 方法返回本身使其可以链式调用
    public Builder callTimeout(long timeout, TimeUnit unit) {
      callTimeout = checkDuration("timeout", timeout, unit);
      return this;
    }
    ...
    // 将此Builder对象传入OkHttpClient构造器
    public OkHttpClient build() {
      return new OkHttpClient(this);
    }
}

Request

创建方式:

Request request = new Request.Builder()
                .url("http://www.baidu.com")
                .get()
                .build();

可以看出用的也是Builder模式

    public Builder() {
      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();
    }

Call

该对象代表一个准备被执行的请求,Call是可以被取消的,Call对象代表了一个request/response 对(Stream)一个call对象一定只能执行一次

创建方式:

 Call call = client.newCall(request);

再来看下OkHttpClient的newCall方法:

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

OkHttpClient实现了Call接口内部的Factory接口,newCall()是Factory接口的抽象方法。
再来看newRealCall()方法,它是个静态方法:

  static RealCall newRealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
    // Safely publish the Call instance to the EventListener.
    // 构造方法是私有的   forWebSocket是否用在WebSocket
    RealCall call = new RealCall(client, originalRequest, forWebSocket);
    call.transmitter = new Transmitter(client, call);
    return call;
  }

RealCall的execute()

先来看下同步方法

  @Override public Response execute() throws IOException {
    synchronized (this) {
      // 首先判断该call是否被执行过,此处表明call对象一定只能执行一次
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    // Transmitter类是OkHttp的应用层和网络层的一个桥梁类
    transmitter.timeoutEnter();
    transmitter.callStart();
    try {
      // client.dispatcher()返回的是client在Builder中初始的dispatcher成员变量
      client.dispatcher().executed(this);
      // 拿到响应,是拦截器链的开端
      return getResponseWithInterceptorChain();
    } finally {
      client.dispatcher().finished(this);
    }
  }

dispatcher的executed()

将call加入同步请求的执行队列中

  synchronized void executed(RealCall call) {
    runningSyncCalls.add(call);
  }

getResponseWithInterceptorChain()

将client中的拦截器和默认的拦截器都加入到集合中,将其传入创建了一个RealInterceptorChain拦截器链。最后返回chain的proceed()的返回值

Response getResponseWithInterceptorChain() throws IOException {
    // Build a full stack of interceptors.
    List<Interceptor> interceptors = new ArrayList<>();
    interceptors.addAll(client.interceptors());
    interceptors.add(new RetryAndFollowUpInterceptor(client));
    interceptors.add(new BridgeInterceptor(client.cookieJar()));
    interceptors.add(new CacheInterceptor(client.internalCache()));
    interceptors.add(new ConnectInterceptor(client));
    if (!forWebSocket) {
      interceptors.addAll(client.networkInterceptors());
    }
    interceptors.add(new CallServerInterceptor(forWebSocket));

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

dispatcher()的finished()

刚开始在dispatcher.executed()里把call加入到runningSyncCalls这个队列中,这里是将其删除。

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

RealCall的equeue()

@Override public void enqueue(Callback responseCallback) {
    // 判断是否执行过
    synchronized (this) {
      if (executed) throw new IllegalStateException("Already Executed");
      executed = true;
    }
    transmitter.callStart();
    // 把这个回调接口封装成AsyncCall对象
    client.dispatcher().enqueue(new AsyncCall(responseCallback));
}

dispatcher.enqueue()

同步请求中只有一个队列,而这里有两个,一个为等待队列一个为执行队列

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.
      // 对异步调用进行变异,使其共享对同一主机的现有运行调用的atomicinteger(原子操作类)
      // atomicinteger能保证多个线程对同一个变量不会同时修改
      if (!call.get().forWebSocket) {
        // 在runningAsyncCalls队列或者readyAsyncCalls队列中找到和call同一主机的call对象
        AsyncCall existingCall = findExistingCallWithHost(call.host());
        if (existingCall != null) call.reuseCallsPerHostFrom(existingCall);
      }
    }
    promoteAndExecute();
}

dispatcher.promoteAndExecute()

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();
        // maxRequests最大并发请求数64
        if (runningAsyncCalls.size() >= maxRequests) break; // Max capacity.
        // maxRequestsPerHost 每个主机的最大请求数5  当前主机请求数大于等于主机最大请求数
        if (asyncCall.callsPerHost().get() >= maxRequestsPerHost) continue; // Host max capacity.

        i.remove();
        asyncCall.callsPerHost().incrementAndGet();
        executableCalls.add(asyncCall);
        runningAsyncCalls.add(asyncCall);
      }
      isRunning = runningCallsCount() > 0;
    }

    for (int i = 0, size = executableCalls.size(); i < size; i++) {
      AsyncCall asyncCall = executableCalls.get(i);
      // executorService()返回一个线程池对象
      // 真正的异步处理方法
      asyncCall.executeOn(executorService());
    }

    return isRunning;
}

AsyncCall

RealCall里面的内部类

final class AsyncCall extends NamedRunnable {
    private final Callback responseCallback;
    private volatile AtomicInteger callsPerHost = new AtomicInteger(0);

    AsyncCall(Callback responseCallback) {
      super("OkHttp %s", redactedUrl());
      this.responseCallback = responseCallback;
    }

    AtomicInteger callsPerHost() {
      return callsPerHost;
    }

    void reuseCallsPerHostFrom(AsyncCall other) {
      this.callsPerHost = other.callsPerHost;
    }

    String host() {
      return originalRequest.url().host();
    }

    Request request() {
      return originalRequest;
    }

    RealCall get() {
      return RealCall.this;
    }

    // 尝试将此异步调用排队到{@code executorservice}。如果执行器已关闭,则此操作将尝试通过将调用报告为失败来进行清理。
    void executeOn(ExecutorService executorService) {
      assert (!Thread.holdsLock(client.dispatcher()));
      boolean success = false;
      try {
        // 让 ExecutorService 中的某個线程执行这個 Runnable 线程
        executorService.execute(this);
        success = true;
      } catch (RejectedExecutionException e) {
        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!
        }
      }
    }
    
    // 和RealCall的execute()方法很像
    @Override protected void execute() {
      boolean signalledCallback = false;
      transmitter.timeoutEnter();
      try {
        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);
      }
    }
 }

AsyncCall继承的NamedRunnable实现Runnable接口。run()里面调用了execute(),它是个抽象方法,具体实现在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();
}

流程图

在这里插入图片描述

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

executorService()

corePoolSize设置为0表示一旦有闲置的线程就可以回收

 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;
 }
 
 public ThreadPoolExecutor(
    int corePoolSize,   // 核心线程数,默认情况下核心线程会一直存活
    int maximumPoolSize,  // 线程池所能容纳的最大线程数
    long keepAliveTime,   // 非核心线程的闲置超时时间,超过这个时间就会被回收
    TimeUnit unit,      // keepAliveTime的单位
    BlockingQueue<Runnable> workQueue,  // 线程池中的任务队列
    ThreadFactory threadFactory // 线程工厂,提供创建新线程的功能
 )

Transmitter

OkHttp的应用程序和网络层之间的桥梁。 此类公开了高级应用程序层原语:连接,请求,响应和流。
RealCall负责的是请求发起和执行,Transmitter则负责请求任务的状态、超时时间、生命周期事件的更新以及请求任务背后的连接、连接池的维护管理等。

构造方法参数

  • OkHttpClient对象
  • RealConnectionPool连接池对象
  • RealCall
  • EventListener监听对象(则一个请求从发起到结束的所有步骤都会被EventListener“看”到)
  • AsyncTimeout超时控制

方法

public Timeout timeout()

返回AsyncTimeout对象

public void timeoutEnter()

创建超时控制

public void timeoutEarlyExit()

在呼叫完成之前停止超时控制

public void callStart()

调用eventListener的callStart方法(绑定call)

public void prepareToConnect(Request request)

准备创建一个流来承载{@code request}。 如果存在连接,则优先使用现有连接。

public boolean canRetry()

是否可以重试

public boolean hasExchange()

是否含有正在执行的交换

public void cancel()

中断请求

public boolean isCanceled()

是否可以中断请求
image

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值