OkHttp拦截器的实现原理
今天项目中遇到需要将从push接收到的数据按照协议parse成应用层需要的结构化数据类型问题;因为push消息类型繁多,等待解析出的结构化数据类型也多样,有的还需要经过几步的parse过程;而且因为项目历史原因,使用Protocal Buffer(push的数据是字节形式的传递)。中间尝试了代理、装饰等模式,都失败了,最终还是使用了原始的继承解决问题;在解决问题个过程中也学习了下OkHttp中的拦截器实现,这里做简单记录:
拦截器的接口定义如下:

可以看到,在拦截器的回调中,我们可以拿到两个重要的参数Request和Response,而接口在回调时,会接收一个Chain类型的参数,这个参数保存了Request和Response的相关数据。
看一个简单的Interceptor接口实现例子:

该拦截器实例的功能只是在请求发出前和接收到响应后,分别打印log。Response response=chain.proceed(request); 很重要,它是将拦截连串起来的关键。
- 再看下,一个网络请求的应用吧:

跟进,OkHttpClient.Builder的addInterceptor()方法,可以看到,在OkHttp内部是使用了List保存了添加的所有拦截器。

- 跟进client.newCall(request).execute();的执行过程,查看拦截器的串联过程:

从上面的方法中可以看到,请求默认会被构造成RealCall类型,再进一步查看RealCall的execute()方法:

上面的红色方框中这行代码,它并没有真正的执行网络请求,而只是简单地将请求放入请求池中,让它等待分派器的后续执行。而真正的执行体在上面的蓝色方框中,它封装了一个拦截器链(Chain),并调用了Chain的proced方法,传入原始的request对象,这里开始拦截器链的调用过程:

- 查看proceed方法,可以看到,它使用循环+递归的方式,借助函数调用栈,将拦截器串联起来:

上面的代码中,真正执行网络请求的是最后一行绿色方框中的代码,而当存在多个拦截器时,每个拦截器在执行时都会在上图的蓝色方框中的代码地方阻塞,等待下一个拦截器的调用返回。
- 为了说明清楚,下面分别以 拦截器链中有1个、2个拦截器的场景加以模拟:

OkHttp拦截器的实现原理的更多相关文章
- struts2拦截器的实现原理
拦截器(interceptor)是Struts2最强大的特性之一,也可以说是struts2的核心,拦截器可以让你在Action和result被执行之前或之后进行一些处理.同时,拦截器也可以让你将通用的 ...
- struts2拦截器的实现原理及源码剖析
拦截器(interceptor)是Struts2最强大的特性之一,也可以说是struts2的核心,拦截器可以让你在Action和result被执行之前或之后进行一些处理.同时,拦截器也可以让你将通用的 ...
- Okhttp拦截器统一异常处理并多次读取response.body().string()
参考:https://blog.csdn.net/a624806998/article/details/73863606 引言: 写这篇文章,因为在自己编写实现Http日志拦截器的时候,在拦截器中使用 ...
- 从网络请求过程看OkHttp拦截器
前言 之前我们结合设计模式简单说了下OkHttp的大体流程,今天就继续说说它的核心部分--拦截器. 因为拦截器组成的链其实是完成了网络通信的整个流程,所以我们今天就从这个角度说说各拦截器的功能. 首先 ...
- Java拦截器的实现原理
对于某个类的A方法进行拦截,在A执行前插入一段代码,A执行后也插入一段代码 原理: 写个拦截器,拦截器中包含要插入前后执行的两段代码 interceptor { C();//C方法 D();//D方法 ...
- mybatis源码分析(5)-----拦截器的实现原理(动态代理+责任链)
写在前面 MyBatsi 的拦截器模式是基于代理的代理模式.并且myBatis 的插件开发也是以拦截器的形式集成到myBatis 当中. MyBatis 的拦截器已经插件是在org.apache.ib ...
- Struts2_day04--课程介绍_Struts2拦截器概述&底层原理_重要的概念
Struts2_day04 上节内容 今天内容 Struts2拦截器概述 拦截器底层原理 重要的概念 自定义拦截器 自定义登录拦截器 Struts2的标签库 Struts2表单标签(会用) Strut ...
- Android 开发 框架系列 OkHttp拦截器
前言 此篇博客只讲解okhttp的拦截器功能的详细使用,如果你还不太了解okhttp可以参考我另外一篇博客 Android 开发 框架系列 OkHttp使用详解 添加Interceptor的简单例子 ...
- Spring 拦截器实现+后台原理(MethodInterceptor)
MethodInterceptor MethodInterceptor是AOP项目中的拦截器(注:不是动态代理拦截器),区别与HandlerInterceptor拦截目标时请求,它拦截的目标是方法. ...
随机推荐
- Jump Game leetcode java
题目: Given an array of non-negative integers, you are initially positioned at the first index of the ...
- jQuery用面向对象的思想来编写验证表单的插件
本人的重点是怎么构建一个简单有效可扩展的jQuery表单验证插件,这篇文章没有教你怎么用 validate plugin.我们的重点在学习一些jQuery,Javascript面向对象编程的知识. 下 ...
- MySQL 动态sql语句运行 用时间做表名
1. 描写叙述 在使用数据的时候,我时候我们须要非常多数据库,并且想用时间来做表名以区分.可是MySQL在存储过程中不支持使用变量名来做表名或者列名. 比方,有一个表我们想以"2015-07 ...
- [Node.js]26. Level 5 : Route rendering
Instead of just writing out the quote to the response, instead render the quote.ejs template, passin ...
- Eclipse.ini參数设置(Maven Integration for Eclipse JDK Warning)
安装EclipseMaven插件后,Eclipse启动问题:Maven Integration for Eclipse JDK Warning. 解决方法: 1. 设置Eclipse使用的JRE为本 ...
- 【转】允许远程用户登录访问mysql的方法
需要手动增加可以远程访问数据库的用户. 方法一.本地登入mysql,更改 "mysql" 数据库里的 "user" 表里的 "host" 项 ...
- jansson的使用
https://jansson.readthedocs.org/en/2.5/gettingstarted.html https://github.com/akheron/jansson/blob/m ...
- uni-app - Class 与 Style 绑定
参考uni文档:https://uniapp.dcloud.io/use?id=class-%E4%B8%8E-style-%E7%BB%91%E5%AE%9A 参考vue文档:https://cn. ...
- Struts2(四)Action一接收参数
一.属性接收参数并输出 导入struts2的包,导入需要的包 和struts.xml配置文件 <?xml version="1.0" encoding="UTF-8 ...
- “最大子序列和”算法 java
maxSubSum各自是最大子序列和的4中java算法实现. 第一种算法执行时间为O(N^3),另外一种算法执行时间为O(N^2),第三种算法执行时间为O(nlogn),第四种算法执行时间为线性N p ...