OkHttp 3.14.10源码分析(2)- OkHttpClient - OkHttp的“ApplicationContext”

2024-01-22 16:08

本文主要是介绍OkHttp 3.14.10源码分析(2)- OkHttpClient - OkHttp的“ApplicationContext”,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

在上一篇文章《OkHttp总体框架介绍》中,我简单的介绍了一下我对OkHttp总体架构设计的一个理解,在文章中,我对OkHttp的各个层次和各个关键的类都做了一个简单的介绍。那这一章节开始,我就开始从更加详细的角度去分析这些关键类的源码,那首当其冲的就是OkHttpClient。

OkHttpClient可以看作是OKHTTP的一个全局应用上下文,在一个应用中往往只会创建一个单例。它主要有两个功能

  • 可配置、存储和获取一些全局的属性配置,比如超时时间、自定义的CookieJar实现、自定义的Interceptor实现、添加事件监听等等。
  • 负责创建和管理一些全局单例对象,比如Dispatcher、ConnectionPool等。
  • 提供newCall API,我们用的最多也是这个API,例如
    String respJson = okHttpClient.newCall(request).execute().body().string();

     

OKhttpClient中大部分的代码都是其属性的配置,并没有什么逻辑上的实现,所以下面我们就从其各个属性开始,去逐步了解OKhttpClient的源码。 

属性

对于OkHttp的属性,我主要根据其特性和层次对其进行分类。但是这里不会出现上一篇文章架构图中描绘的所有类,因为那图中的类或者接口不是所有都对外开放的,一些是内部使用的API,例如:Transmitter、Exchange、Connection这些都不会出现在OKHttpClient中。

基础配置

这些属性主要是一些全局性的基础配置,它们中大部分都是对用户开放的,可获取可设置。它们会存储在OkHttp实例当中,并且会在全局范围内被各个层次的模块使用,主要是用来控制通信的一些基本行为,比如请求超时时间,是否SSL重定向,是否Http重定向,是否使用缓存、支持的协议等。

//协议簇-只支持HTTP_2/HTTP_1_1,并且不可修改
static final List<Protocol> DEFAULT_PROTOCOLS = Util.immutableList(Protocol.HTTP_2/, Protocol.HTTP_1_1);
//默认连接规范
//ConnectionSpec.CLEARTEXT:Http的规范配置
//ConnectionSpec.MODERN_TLS:TLS规范配置
static final List<ConnectionSpec> DEFAULT_CONNECTION_SPECS = Util.immutableList(ConnectionSpec.MODERN_TLS,ConnectionSpec.CLEARTEXT);
//是否SSL重定向
final boolean followSslRedirects;
//是否http重定向
final boolean followRedirects;
//请求超时(connect + write + read)默认没限制
final int callTimeout;
//连接超时(对应tcp connect())
final int connectTimeout;
//读取超时(对应TCP read())默认10s
final int readTimeout;
//写入超时(对应TCP write())默认10s
final int pingInterval;
//ping周期
final int writeTimeout;

线程资源管理层

这一层次的类只有Dispatcher一个。

final Dispatcher dispatcher;

OkHttpClient.Buider会使用其的无参构造函数创建一个默认的实现,无参构造函数会使用内置的线程池来执行异步任务。

public Builder() {dispatcher = new Dispatcher();...
}

Dispatcher主要是实现异步请求任务策略,负责分配异步线程资源,控制异步连接数,只覆盖线程资源层面的逻辑,往下的执行过程对其来说是透明的。对于同步任务,Dispatcher只是简单记录当前运行的任务实体(RealCall),并且是由RealCall主动注册和注销。
你可以通过OkHttpClient.Builder和Dispatvher有参构造函数来指定执行异步任务的线程池。

//这里出于演示目的,只是创建了一个简单的线程池,真正使用需要用户根据自己的应用场景配置自己的线程池。
Executor executor = Executors.newSingleThreadExecutor();
OkHttpClient client = new OkHttpClient.Builder().dispatcher(new Dispatcher(executor)).build();

应用层协议(Http)实现

//用户自定义拦截器,默认为空,会被添加到Interceptor调用链的最前端
final List<Interceptor> interceptors;
//用户自定义拦截器,默认为空,拦截所有非WebSocket的请求和响应。
//该集合会被添加到Connect完成后和数据发送前的中间
final List<Interceptor> networkInterceptors;
//自定义CookieJar,系统默认只有一个空实现,如果用户想实现Cookie功能,需要自己实现该接口,并且设置到OKHttpClient中。
final CookieJar cookieJar;
//实现了Http协议的缓存规范,默认为空。
final @Nullable Cache cache;

连接池

//连接池
final ConnectionPool connectionPool;

ConnectionPool是一个final类,同时它并没有实现连接池的功能,而是委派给RealConnectionPool来实现:

public final class ConnectionPool {final RealConnectionPool delegate;//默认参数public ConnectionPool() {this(5, 5, TimeUnit.MINUTES);}//用户可以通过该构造方法指定一些线程池的配置参数public ConnectionPool(int maxIdleConnections, long keepAliveDuration, TimeUnit timeUnit) {this.delegate = new RealConnectionPool(maxIdleConnections, keepAliveDuration, timeUnit);}//下面三个方法都是通过委派给RealConnection实例完成public int idleConnectionCount() {return delegate.idleConnectionCount();}...
}

ConnectionPool 虽然是不可扩展的,但是你可以通过这样的方式修改ConnectionPool 的默认参数:

OkHttpClient okHttpClient = new OkHttpClient().newBuilder()//最大空闲连接数是10,空闲连接存活时间是15分钟.connectionPool(new ConnectionPool(10,15, TimeUnit.MINUTES)).build();

传输层

//代理服务设置,默认为空
final @Nullable Proxy proxy;
//代理选择器,默认为空
//对于Proxy和ProxySelector的使用,小伙伴可以参考JDK官方文档,机翻一下应该看懂也不难。
//https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html
final ProxySelector proxySelector;
//Socket工厂类,默认为DefaultSocketFactory。你可以自定义自己的SocketFacotry。
final SocketFactory socketFactory;
//SSLSocket工厂类,默认SSLSocketFactoryImpl,也可以自定义。
final SSLSocketFactory sslSocketFactory;
//SSL主机名验证
final HostnameVerifier hostnameVerifier;
//下面两个是对SSL证书的处理
final CertificateChainCleaner certificateChainCleaner;
final CertificatePinner certificatePinner;
//代理权限认证
final Authenticator proxyAuthenticator;
//代理权限认证
final Authenticator authenticator;
//DNS解析
final Dns dns;

内部使用类

static {//OKHttp内部类,主要代理了一些OKHttp重用的内部API,//方便后序OKHttp升级,如果后期某个API从语义上改变了,只需要修改Internal里面相应的代理方法即可Internal.instance = new Internal() {...}
}

总结

到这里,我们就对OkHttpClient进行了一遍初略的了解,了解它到底有哪些属性,并对这些属性的作用进行了一个简单的归类,同时指出了哪些是可以自定义扩展和配置的。
在后面我们会对OkHttp其他的一些关键的实现类,进行详细的源码分析,如果文章有什么问题,也欢迎大家指出。

这篇关于OkHttp 3.14.10源码分析(2)- OkHttpClient - OkHttp的“ApplicationContext”的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/633490

相关文章

MySQL中的表连接原理分析

《MySQL中的表连接原理分析》:本文主要介绍MySQL中的表连接原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、表连接原理【1】驱动表和被驱动表【2】内连接【3】外连接【4编程】嵌套循环连接【5】join buffer4、总结1、背景

python中Hash使用场景分析

《python中Hash使用场景分析》Python的hash()函数用于获取对象哈希值,常用于字典和集合,不可变类型可哈希,可变类型不可,常见算法包括除法、乘法、平方取中和随机数哈希,各有优缺点,需根... 目录python中的 Hash除法哈希算法乘法哈希算法平方取中法随机数哈希算法小结在Python中,

Java Stream的distinct去重原理分析

《JavaStream的distinct去重原理分析》Javastream中的distinct方法用于去除流中的重复元素,它返回一个包含过滤后唯一元素的新流,该方法会根据元素的hashcode和eq... 目录一、distinct 的基础用法与核心特性二、distinct 的底层实现原理1. 顺序流中的去重

关于MyISAM和InnoDB对比分析

《关于MyISAM和InnoDB对比分析》:本文主要介绍关于MyISAM和InnoDB对比分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录开篇:从交通规则看存储引擎选择理解存储引擎的基本概念技术原理对比1. 事务支持:ACID的守护者2. 锁机制:并发控制的艺

MyBatis Plus 中 update_time 字段自动填充失效的原因分析及解决方案(最新整理)

《MyBatisPlus中update_time字段自动填充失效的原因分析及解决方案(最新整理)》在使用MyBatisPlus时,通常我们会在数据库表中设置create_time和update... 目录前言一、问题现象二、原因分析三、总结:常见原因与解决方法对照表四、推荐写法前言在使用 MyBATis

Python主动抛出异常的各种用法和场景分析

《Python主动抛出异常的各种用法和场景分析》在Python中,我们不仅可以捕获和处理异常,还可以主动抛出异常,也就是以类的方式自定义错误的类型和提示信息,这在编程中非常有用,下面我将详细解释主动抛... 目录一、为什么要主动抛出异常?二、基本语法:raise关键字基本示例三、raise的多种用法1. 抛

github打不开的问题分析及解决

《github打不开的问题分析及解决》:本文主要介绍github打不开的问题分析及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、找到github.com域名解析的ip地址二、找到github.global.ssl.fastly.net网址解析的ip地址三

Mysql的主从同步/复制的原理分析

《Mysql的主从同步/复制的原理分析》:本文主要介绍Mysql的主从同步/复制的原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录为什么要主从同步?mysql主从同步架构有哪些?Mysql主从复制的原理/整体流程级联复制架构为什么好?Mysql主从复制注意

java -jar命令运行 jar包时运行外部依赖jar包的场景分析

《java-jar命令运行jar包时运行外部依赖jar包的场景分析》:本文主要介绍java-jar命令运行jar包时运行外部依赖jar包的场景分析,本文给大家介绍的非常详细,对大家的学习或工作... 目录Java -jar命令运行 jar包时如何运行外部依赖jar包场景:解决:方法一、启动参数添加: -Xb

Apache 高级配置实战之从连接保持到日志分析的完整指南

《Apache高级配置实战之从连接保持到日志分析的完整指南》本文带你从连接保持优化开始,一路走到访问控制和日志管理,最后用AWStats来分析网站数据,对Apache配置日志分析相关知识感兴趣的朋友... 目录Apache 高级配置实战:从连接保持到日志分析的完整指南前言 一、Apache 连接保持 - 性