OkHttp平台抽象机制分析
概述
OkHttp使用平台抽象机制来处理不同平台(JVM、Android)上的特定实现,特别是TLS/SSL相关的功能。这种设计允许OkHttp在不同环境中无缝运行,同时利用各平台特有的优化和功能。
核心组件
Platform抽象类
Platform
是OkHttp平台抽象的核心,定义了跨平台操作的接口,主要包括:
- TLS配置
- 证书验证
- 日志记录
- Socket配置
- 信任管理器处理
PlatformRegistry
PlatformRegistry
负责在运行时选择合适的平台实现。它在JVM和Android平台上有不同的实现:
JVM平台实现
JVM版本的PlatformRegistry
按以下优先级选择平台:
ConscryptPlatform
- 如果Conscrypt可用OpenJSSEPlatform
- 如果OpenJSSE可用BouncyCastlePlatform
- 如果BouncyCastle可用Jdk9Platform
- 适用于JDK 9+或JDK 8 build 252+Jdk8WithJettyBootPlatform
- 适用于JDK 8- 默认
Platform
实现
Android平台实现
Android版本的PlatformRegistry
按以下优先级选择平台:
Android10Platform
- 适用于Android 10+ (API 29+)AndroidPlatform
- 适用于Android 5-9 (API 21-28)- 默认
Platform
实现
平台实现特点(详见OkHttp平台抽象机制深度解析)
Jdk9Platform
- 使用Java 9引入的标准API进行ALPN配置
- 通过
SSLParameters.applicationProtocols
和SSLSocket.applicationProtocol
支持协议协商 - 不支持通过反射获取SSLSocketFactory的TrustManager(JDK 9+的模块化限制)
- 优先使用TLSv1.3(如果可用)
Jdk8WithJettyBootPlatform
- 使用反射和Jetty的ALPN启动类来支持TLS扩展
- 为JDK 8提供ALPN支持
AndroidPlatform(详见OkHttp之AndroidPlatform类分析)
- 适用于Android 5-9 (API 21-28)
- 使用Android特定的API进行TLS配置
- 通过反射访问Android内部API
Android10Platform
- 适用于Android 10+ (API 29+)
- 使用Android 10引入的标准API进行ALPN配置
- 不再需要通过反射访问内部API
特殊平台实现
ConscryptPlatform
: 使用Conscrypt提供的安全功能OpenJSSEPlatform
: 使用OpenJSSE提供的安全功能BouncyCastlePlatform
: 使用BouncyCastle提供的安全功能
平台关系图
classDiagram
Platform <|-- Jdk9Platform
Platform <|-- Jdk8WithJettyBootPlatform
Platform <|-- ConscryptPlatform
Platform <|-- OpenJSSEPlatform
Platform <|-- BouncyCastlePlatform
Platform <|-- AndroidPlatform通过SocketAdapter做类似JVM的降级策略
Platform <|-- Android10Platform
class Platform {
<>
+configureTlsExtensions()
+getSelectedProtocol()
+trustManager()
+newSSLContext()
+buildCertificateChainCleaner()
+buildTrustRootIndex()
+isCleartextTrafficPermitted()
+log()
+static buildPlatform()
}
class PlatformRegistry {
<>
+findPlatform()
}
class JvmPlatformRegistry {
+findPlatform()
}
class AndroidPlatformRegistry {
+findPlatform()
}
PlatformRegistry <|.. JvmPlatformRegistry
PlatformRegistry <|.. AndroidPlatformRegistry
平台选择流程
flowchart TD
A[Platform.buildPlatform] --> B{平台类型?}
B -->|JVM| C[JvmPlatformRegistry.findPlatform]
B -->|Android| D[AndroidPlatformRegistry.findPlatform]
C --> C1{Conscrypt可用?}
C1 -->|是| C2[ConscryptPlatform]
C1 -->|否| C3{OpenJSSE可用?}
C3 -->|是| C4[OpenJSSEPlatform]
C3 -->|否| C5{BouncyCastle可用?}
C5 -->|是| C6[BouncyCastlePlatform]
C5 -->|否| C7{JDK 9+或JDK 8 build 252+?}
C7 -->|是| C8[Jdk9Platform]
C7 -->|否| C9{JDK 8?}
C9 -->|是| C10[Jdk8WithJettyBootPlatform]
C9 -->|否| C11[默认Platform]
D --> D1{Android 10+?}
D1 -->|是| D2[Android10Platform]
D1 -->|否| D3{Android 5 - 9?}
D3 -->|是| D4[AndroidPlatform]
D4 --> D41{ConscryptSocketAdapter支持?}
D41 -->|是| D42[使用ConscryptSocketAdapter]
D41 -->|否| D43{BouncyCastleSocketAdapter支持?}
D43 -->|是| D44[使用BouncyCastleSocketAdapter]
D43 -->|否| D45{AndroidSocketAdapter支持?}
D45 -->|是| D46[使用AndroidSocketAdapter]
D45 -->|否| D47[使用默认SocketAdapter处理]
D3 -->|否| D5{API版本=0?}
D5 -->|是| D6[Jdk9Platform或默认Platform]
D5 -->|否| D7[抛出异常]
结论
OkHttp的平台抽象机制通过Platform
类和PlatformRegistry
实现了优雅的跨平台支持。这种设计使OkHttp能够在不同的Java和Android环境中利用平台特定的功能,同时保持一致的API。平台选择是自动的,基于运行时环境和可用的安全提供者,确保OkHttp始终使用最佳的可用实现。