okhttp(二) 拦截器
okhttp(二) 拦截器
在前文中讲到了okhttp中的分发器
接下来讲okhttp中的拦截器
在上文中讲到,同步执行excuet时,会通过 getResponseWithInterceptorChain 获取response,
在异步enqueue后,后面会调用AsyncCall中execute,而里面也是通过getResponseWithInterceptorChain 来获取response。
调用的都是RealCall中的getResponseWithInterceptorChain函数。
getResponseWithInterceptorChain
1 | Response getResponseWithInterceptorChain() throws IOException { |
一个数组,添加各个拦截器,
然后初始化一个 Interceptor.Chain 对象,注意第2、3、4个参数都是null,而第5个参数是index:0
然后调用proceed函数
RealInterceptorChain.java
RealInterceptorChain 实现 Interceptor接口中的Chain接口。
1 | public final class RealInterceptorChain implements Interceptor.Chain { |
上面是RealInterceptorChain的全部代码,注意看一段代码
1 | // 最开始index = 0,注意这里构造RealInterceptorChain时,传入的为index+1 |
看注释现在可能又点绕,接着往下看,Interceptor是一个接口,没必要看,可以直接先看RetryAndFollowUpInterceptor
RetryAndFollowUpInterceptor 重试以及重定向拦截器
RetryAndFollowUpInterceptor 实现 Interceptor 接口
查看其中的intercept函数
1 | @Override |
可以看到此处的主要逻辑,
将传入的chain对象转为RealInterceptorChain,
无限循环,然后在循环中调用chain.proceed函数,获取response,
循环的主要作用为catch异常,并针对RouteException 或者 IOException 做重试操作,其他异常则终止,
而chain.proceed又会回到上面RealInterceptorChain中
1 |
|
BridgeInterceptor 负责把用户构造的请求转换为发送给服务器的请求,把服务器返回的响应转换为对用户友好的响应
BridgeInterceptor 也是实现 Interceptor 接口
同样直接查看intercept函数
1 | @Override |
可以看到,这个函数的逻辑,
先对请求头信息进行再处理,然后执行chain.proceed获取networkResponse,
然后再对networkResponse进行再包装处理
同RetryAndFollowUpInterceptor一样,又会调用到chain.proceed函数,
又会回到上面RealInterceptorChain中
1 | // 当从RetryAndFollowUpInterceptor再过来时,index = 2; index + 1 = 3; |
再看CacheInterceptor代码
CacheInterceptor 负责读取缓存以及更新缓存
CacheInterceptor 也是实现 Interceptor 接口
1 | @Override |
过程就是获取一个networlRequets,以及一个缓存的cacheResponse,
如果networlRequets与cacheResponse,则直接报504的网络异常
如果networlRequets为空,则只能返回cacheResponse,
如果networlRequets不为空,则执行网络请求,获取networkResponse,
如果cacheResponse 不为空 且 networkResponse响应码304,代表无更改,则可以返回,
再往下就是对networlRequets进行处理,并加入缓存。
注意:此处获取networkResponse也是调用chain.proceed,于是与上面一直,也会走到 RealInterceptorChain中。
1 | // 当从RetryAndFollowUpInterceptor再过来时,index = 3; index + 1 = 4; |
此时会调用到ConnectInterceptor中的intercept函数
ConnectInterceptor
ConnectInterceptor 也是实现 Interceptor 接口
1 | public final class ConnectInterceptor implements Interceptor { |
如上代码就是ConnectInterceptor类中所有源码,
intercept函数中,重新获取了几个参数,和上面的几个Interceptor实现类不太一样,
最后调用的proceed函数是四个参数的,最后还是会走到 RealInterceptorChain中。
1 | // 当从RetryAndFollowUpInterceptor再过来时,index = 4; index + 1 = 5; |
CallServerInterceptor
CallServerInterceptor 也是实现 Interceptor 接口,
CallServerInterceptor 中 intercept 函数就是直接与服务端通信的,
而在这里会获取到真正的response,并返回到上一层,也就是ConnectInterceptor的intercept,同理会依次向上返回。
责任链模式
在上面看到的,一层一层拦截器向下调用,Interceptor类实现 调用 Interceptor类实现,
每一层的拦截器实现自己的功能,然后交付给下一层拦截器,
这种设计模式就是责任链模式。