okhttp3.9.1源码初探
- 简单调用方式
- get同步调用调用
public class GetExample {
//1.创建OkHttpClient对象
OkHttpClient client = new OkHttpClient();
String run(String url) throws IOException {
//2.通过Builder建造者模式创建Request对象
Request request = new Request.Builder()
.url(url)
.build();
//3.通过client.newCall(request)方法传入Request对象得到Call对象,调用execute()方法同步获取请求结果Response
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
}
public static void main(String[] args) throws IOException {
GetExample example = new GetExample();
String response = example.run("https://raw.github.com/square/okhttp/master/README.md");
System.out.println(response);
}
}
- get异步调用
就是获取Call对象之后调用enqueue(Callback)方法传入Callback回调,获取请求结果Response
- 同步调用流程
client对象和request对象创建之后client会调用newCall方法获取Call对象,代码如下
/**
* Prepares the {@code request} to be executed at some point in the future.
*/
@Override public Call newCall(Request request) {
return RealCall.newRealCall(this, request, false /* for web socket */);
}
如上,在okhttpclient类中,调用newCall方法会执行
RealCall.newRealCall(this, request, false /* for web socket */);
方法
查看RealCall类中该方法如下
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;
}
如上,在该方法中常见了RealCall对象并返回
RealCall的构造方法如下
private RealCall(OkHttpClient client, Request originalRequest, boolean forWebSocket) {
this.client = client;
this.originalRequest = originalRequest;
this.forWebSocket = forWebSocket;
this.retryAndFollowUpInterceptor = new RetryAndFollowUpInterceptor(client, forWebSocket);
}
如上,在RealCall方法中保存了传入的参数,并创建了RetryAndFollowUpInterceptor,重定向拦截器。
接着RealCall调用了excute()方法
@Override public Response execute() throws IOException {
synchronized (this) {
if (executed) throw new IllegalStateException("Already Executed");
executed = true;
}
captureCallStackTrace();
eventListener.callStart(this);
try {
//关注点1.通过client调用dispacher()方法获取Dispacher对象,并调用其executed方法
client.dispatcher().executed(this);
//关注点2.调用getResponseWithInterceptorChain();方法
Response result = getResponseWithInterceptorChain();
if (result == null) throw new IOException("Canceled");
return result;
} catch (IOException e) {
eventListener.callFailed(this, e);
throw e;
} finally {
client.dispatcher().finished(this);
}
}
关注点1:client如何通过dispacher()方法获取Dispacher对象的,查看client的dispacher()方法如下
public Dispatcher dispatcher() {
return dispatcher;
}
直接返回了dispacher对象,那它在何时创建的,通过查看源码发现okhttpclient也是通过Builder模式创建的,其内部类Builder在构造方法中创建了Dispacher对象,代码如下:
public Builder() {
//在这里创建了dispacher对象
dispatcher = new Dispatcher();
protocols = DEFAULT_PROTOCOLS;
connectionSpecs = DEFAULT_CONNECTION_SPECS;
eventListenerFactory = EventListener.factory(EventListener.NONE);
proxySelector = ProxySelector.getDefault();
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;
connectTimeout = 10_000;
readTimeout = 10_000;
writeTimeout = 10_000;
pingInterval = 0;
}
然后调用dispacher的excute()方法,代码如下:
/** Used by {@code Call#execute} to signal it is in-flight. */
synchronized void executed(RealCall call) {
//发现只是加入了runningSyncCall队列
runningSyncCalls.add(call);
}
Dispacher对象初始化时创建了三个队列用来存放call
/** Ready async calls in the order they'll be run. 准备异步执行的Call队列*/
private final Deque<AsyncCall> readyAsyncCalls = new ArrayDeque<>();
/** Running asynchronous calls. Includes canceled calls that haven't finished yet.正在执行的异步Call队列 */
private final Deque<AsyncCall> runningAsyncCalls = new ArrayDeque<>();
/** Running synchronous calls. Includes canceled calls that haven't finished yet. 正在异性的同步Call队列*/
private final Deque<RealCall> runningSyncCalls = new ArrayDeque<>();
然后看关注点2:调用getResponseWithInterceptorChain();方法,方法如下:
Response getResponseWithInterceptorChain() throws IOException {
// Build a full stack of interceptors.
//1.创建了一个存放拦截器的数组
List<Interceptor> interceptors = new ArrayList<>();
//2.将okhttpclient中设置的拦截器添加到数组中
interceptors.addAll(client.interceptors());
//3.添加重定向拦截器
interceptors.add(retryAndFollowUpInterceptor);
//4.添加桥接拦截器,主要用来构造请求参数及请求结果
interceptors.add(new BridgeInterceptor(client.cookieJar()));
//5.添加缓存拦截器
interceptors.add(new CacheInterceptor(client.internalCache()));
//6.添加链接拦截器
interceptors.add(new ConnectInterceptor(client));
if (!forWebSocket) {
//7.添加网络拦截器
interceptors.addAll(client.networkInterceptors());
}
//8.添加访问拦截器
interceptors.add(new CallServerInterceptor(forWebSocket));
//9.创建RealInterceptorChain对象
Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,
originalRequest, this, eventListener, client.connectTimeoutMillis(),
client.readTimeoutMillis(), client.writeTimeoutMillis());
//10.调用procceed()方法执行
return chain.proceed(originalRequest);
}
接下来就是各种拦截器的相关知识,okHttp采用责任链模式来处理请求和请求结果,从上到下依次是
retryAndFollowUpInterceptor,BridgeInterceptor,CacheInterceptor,ConnectInterceptor,CallServerInterceptor。