早年写过一篇关于OkHttp的文章,只是不太深入,有兴趣的可以看看,也讲到一些OkHttp的基础使用:
OkHttp核心源码分析_AD钙奶-lalala的博客-CSDN博客我们学习技术的时候,一开始是会用,进阶就是深入理解其原理,然而各路框架源码,系统源码又极为庞大,我们就必须知道如何去领会其中的核心思想。今天我们就一起来理一理OkHttp的核心源码,做到知其然知其所以然!OKHttp的使用:OkHttpClient okHttpClient = new OkHttpClient();一开始我们需要初始化OkHttpClient,这里使用的是一个无参构...https://blog.csdn.net/qq_36428821/article/details/104353749这篇两年前的文章我仔细看了一下,基本上调度器这一块已经讲的很透彻了,今天就不再浪费时间去讲调度器相关知识了。那么今天接着重点讲一下拦截器,我看以前的文章里面一笔带过了,估计当时我也不太理解。
我们知道OkHttp执行异步任务底层其实是使用了线程池,执行的任务会走到AsyncCall的下面的方法:
- protected void execute() {
- boolean signalledCallback = false;
- transmitter.timeoutEnter();
- try {
- Response response = getResponseWithInterceptorChain();//1
- 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);
- }
- } catch (Throwable t) {
- cancel();
- if (!signalledCallback) {
- IOException canceledException = new IOException("canceled due to " + t);
- canceledException.addSuppressed(t);
- responseCallback.onFailure(RealCall.this, canceledException);
- }
- throw t;
- } finally {
- client.dispatcher().finished(this);
- }
- }
我们要讲拦截器,首先就要讲一个设计模式:责任链模式。那么有同学可能会问什么是责任链模式呢?我就举个订外卖的例子:我们通过美团发起请求,然后美团将订购信息发给饭店,饭店再将信息传给厨师,厨师做好饭后将结果返回给饭店,饭店在将结果返回给美团。这样的过程差不多就是责任链模式。责任链模式可以理解为一个U型的结构。
我们进到注释1看看:
- Response getResponseWithInterceptorChain() throws IOException {
- // Build a full stack of interceptors.
- List
interceptors = new ArrayList<>(); - interceptors.addAll(client.interceptors());//1
- 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);//2
- 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);
- }
- }
- }
OkHttp五大拦截器:
RetryAndFollowUpInterceptor(重试和重定向拦截器)
第一个接触到请求,最后接触到响应;负责判断是否需要重新发起整个请求
BridgeInterceptor(桥接拦截器)
补全请求,并对响应进行额外处理
CacheInterceptor(缓存拦截器)
请求前查询缓存,获得响应并判断是否需要缓存
ConnectInterceptor(链接拦截器)
与服务器完成TCP连接 (Socket)
CallServerInterceptor(请求服务拦截器)
与服务器通信;封装请求数据与解析响应数据(如:HTTP报文)
我们注意注释1处,这个是我们自己定义的拦截器,比如常用的日志拦截器。注释2处调用以后,最开始执行自定义的拦截器,然后调用重试和重定向拦截器->桥接拦截器->缓存拦截器->链接拦截器->请求服务拦截器,数据返回经过请求服务拦截器->链接拦截器->缓存拦截器->桥接拦截器->重试和重定向拦截器->自定义拦截器。
拦截器执行流程图如下:
拦截器的设计也很好的凸现了设计模式中的单一职责原则。