《OkHttp源码分析》之 OkHttp的请求拦截链

07

1-2018

Mirs_sir

博客:http://my.csdn.net/a109340

声明:本文由作者 Mirs_sir 授权发布,未经原作者允许请勿转载

感谢 Mirs_sir 为我们带来OkHttp源码分析系列文章,目录如下:


  • 1.Http请求原理

  • 2.OkHttp的简单使用

  • 3.OkHttp的初始化

  • 4.OkHttp请求流程分析

  • 5.OkHttp的请求拦截链

  • 6.OkHttp请求调度的分析

  • 7.OkHttp的缓存管理

  • 8.深入源码理解HashMap、LinkedHashMap,DiskLruCache


日更一篇,敬请期待哦


小编温馨提示:代码块向右滑动可查看更多代码,长按可复制代码哟

OkHttp的请求拦截链

OkHttp request interception chain


OkHttp请求的核心处理就是这一系列的拦截链


Response getResponseWithInterceptorChain() throws IOException { 
// Build a full stack of interceptors. 
//建立一个完整的拦截器堆栈。 
List interceptors = new ArrayList<>(); 
//OkHttp初始化添加的拦截器 
interceptors.addAll(client.interceptors()); 
interceptors.add(retryAndFollowUpInterceptor); 
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, null, null, null, 0, originalRequest);
return chain.proceed(originalRequest);
} 


这里面看到 ,第一个add的是client里面自己定义的拦截链集合和如果不是webSocket的话能添加客户端网络的拦截链,然后后面依次添加的拦截器有


RetryAndFollowUpInterceptor 重试和跟进拦截器
BridgeInterceptor           桥拦截器
CacheInterceptor            缓存拦截器
ConnectInterceptor          链接拦截器
CallServerInterceptor       呼叫服务拦截器
RealInterceptorChain        实际拦截链,其中携带整个拦截器链:所有应用拦截器,OkHttp核心,所有网络拦截器,最后是网络呼叫者。


这种链式调用在设计模式里有个叫责任链模式,这个的话我们进去看下源码印证一下,因为他这个集合是一个带有泛型的,所以直接看他的泛型


/** 
* Observes, modifies, and potentially short-circuits requests going out and the corresponding 
* responses coming back in. Typically interceptors add, remove, or transform headers on the request 
* or response. 
* 观察,修改和潜在地短路请求以及相应的响应。通常,拦截器会在请求或响应中添加,删除或变换头文件。 
*/ 
public interface Interceptor { 
Response intercept(Chain chain) throws IOException;
interface Chain { 
Request request();
Response proceed(Request request) throws IOException;
Connection connection();
} 
}


然后再看RealInterceptorChain的代码因为后面调用的是他的proceed方法,可以知道他肯定是实现了Interceptor的Chain,我们先来看他的初始化的过程


Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0, originalRequest); 


直接看他的构造函数
public RealInterceptorChain(List<Interceptor> interceptors, StreamAllocation streamAllocation, 
HttpCodec httpCodec, RealConnection connection, int index, Request request) { 
this.interceptors = interceptors; 
this.connection = connection; 
this.streamAllocation = streamAllocation; 
this.httpCodec = httpCodec; 
this.index = index; 
this.request = request; 
} 


为null的先不管,看那些不为null的, 传过来了一个请求链,index是0,还有request 接着调用了RealInterceptorChain的proceed方法


java 
@Override public Response proceed(Request request) throws IOException { 
return proceed(request, streamAllocation, httpCodec, connection); 
}
public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec, 
RealConnection connection) throws IOException { 
if (index >= interceptors.size()) throw new AssertionError();
calls++;
// If we already have a stream, confirm that the incoming request will use it.
//如果我们已经有一个流,请确认传入的请求将使用它
if (this.httpCodec != null && !this.connection.supportsUrl(request.url())) {
  throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
      + " must retain the same host and port");
}
// If we already have a stream, confirm that this is the only call to chain.proceed().
//如果我们已经有一个流,确认这是唯一的call在chain.proceed()中
if (this.httpCodec != null && calls > 1) {
  throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
      + " must call proceed() exactly once");
}
// Call the next interceptor in the chain.
// 调用链中的下一个拦截器
RealInterceptorChain next = new RealInterceptorChain(
    interceptors, streamAllocation, httpCodec, connection, index + 1, request);
Interceptor interceptor = interceptors.get(index);
Response response = interceptor.intercept(next);
// Confirm that the next interceptor made its required call to chain.proceed().
//  确认下一个拦截器将其所需的调用链接到chain.proceed()
if (httpCodec != null && index + 1 < interceptors.size() && next.calls != 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值