一、核心设计思想

OkHttp 的核心架构是 “请求分发 + 拦截器链” 模式,主要基于以下几个设计模式:

设计模式应用场景
建造者模式OkHttpClientRequest 的构建
门面模式OkHttpClient 作为统一入口,隐藏内部复杂性
责任链模式拦截器链,将请求的发送者和接收者解耦

责任链模式是 OkHttp 的精髓——将网络请求的各个阶段封装到不同的拦截器中,串成一条链,请求沿着链依次传递,每个拦截器各司其职。

二、整体架构流程

同步

异步

创建 OkHttpClient

构建 Request

client.newCall 创建 RealCall

请求类型

Call.execute

Call.enqueue

Dispatcher.executed
加入 runningSyncCalls

Dispatcher.enqueue
判断并发限制

是否超过
maxRequests=64 或
单Host=5?

加入 runningAsyncCalls
线程池执行

加入 readyAsyncCalls
等待队列

getResponseWithInterceptorChain

拦截器链处理

返回 Response

Dispatcher.finished
移除队列并调度等待任务

2.1 三个核心角色

使用 OkHttp 发起请求时,最少涉及三个角色:

  • OkHttpClient:全局配置容器(代理、SSL、超时、缓存等),建议作为单例
  • Request:封装 URL、Header、Body 等请求信息
  • Call(实际为 RealCall):代表一个已准备好执行的请求,通过 client.newCall(request) 获得

2.2 Dispatcher(分发器)

Dispatcher 负责请求的调度管理,内部包含:

成员说明默认值
maxRequests最大并发请求数64
maxRequestsPerHost单域名最大并发数5
readyAsyncCalls异步等待队列
runningAsyncCalls异步执行队列
runningSyncCalls同步执行队列
executorService线程池类似 CachedThreadPool

同步请求:直接加入 runningSyncCalls 记录,由调用方线程执行。

异步请求:判断是否超过并发限制——未超过则加入执行队列并提交线程池;超过则先进入等待队列。每次请求完成后,Dispatcher.finished() 会触发等待队列中的任务出队执行。

三、拦截器链(核心)

getResponseWithInterceptorChain() 是 OkHttp 最核心的方法,它按顺序构建拦截器列表:

应用拦截器
client.interceptors

RetryAndFollowUpInterceptor
重试与重定向

BridgeInterceptor
请求/响应适配

CacheInterceptor
缓存处理

ConnectInterceptor
建立连接

网络拦截器
client.networkInterceptors

CallServerInterceptor
读写数据

3.1 各拦截器职责

拦截器职责
应用拦截器(自定义)用户添加,最先执行,可处理公共参数、Header 等
RetryAndFollowUpInterceptor连接失败自动重试、处理重定向
BridgeInterceptor补全请求头(Content-Type、Content-Length、Host、Cookie 等),解压 GZIP 响应
CacheInterceptor根据 HTTP 缓存策略,判断是否使用缓存
ConnectInterceptor从连接池获取或新建 TCP 连接
网络拦截器(自定义)用户添加,在连接建立后、数据读写前执行,常用于监控网络层数据
CallServerInterceptor最后一个拦截器,通过 HttpCodec 向服务器写出请求数据、读取响应数据

3.2 责任链传递机制

每个拦截器的 intercept(Chain chain) 方法分为三部分:

  1. 预处理:处理当前拦截器自身的逻辑
  2. 传递:调用 chain.proceed(request) 将请求交给下一个拦截器
  3. 后处理:下一个拦截器返回 Response 后的后续处理

四、连接池与连接复用

TCP 连接需要三次握手,开销较大。OkHttp 通过 连接池(ConnectionPool) 复用 TCP 连接来减少延迟。

请求到达 ConnectInterceptor

根据 Address
查找可用连接

连接池中
是否有可用连接?

复用已有连接

创建新连接
TCP三次握手

存入连接池

执行请求

请求完成

连接归还连接池
不立即关闭

连接池清理线程
清理闲置连接

4.1 连接复用的关键点

  • Address:由 URL 的 Scheme、Host、Port 以及 OkHttpClient 的配置(如 HTTPS 设置)共同决定。相同 Address 的请求可共享同一个 Socket 连接。
  • 连接池策略:请求完成后连接不立即关闭,而是放回连接池供后续复用。
  • 清理机制:连接池有后台清理线程,定期关闭闲置连接。

4.2 应用拦截器 vs 网络拦截器

面试常见问题:

应用拦截器网络拦截器
执行时机最早执行,在重试和重定向之前ConnectInterceptor 之后、CallServerInterceptor 之前
调用次数只调用一次可能调用多次(每次重试/重定向都会调用)
适用场景公共参数注入、日志打印网络监控、流量统计

五、面试回答要点总结

回答“OkHttp 原理”时,可以按以下逻辑串联:

  1. 一句话概括:OkHttp 基于责任链模式,通过拦截器链处理请求的各个阶段,配合Dispatcher调度请求,连接池复用 TCP 连接。

  2. 流程简述OkHttpClient + RequestRealCallexecute()/enqueue()Dispatcher 调度 → getResponseWithInterceptorChain() → 拦截器链依次处理 → 返回 Response

  3. 亮点展开(挑 1-2 个深入):

    • 拦截器链:7 个拦截器的职责和顺序
    • 连接池Address 决定连接复用,减少三次握手开销
    • Dispatcher:并发控制(64/5)和线程池调度
Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐