今天项目中遇到需要将从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拦截器的实现原理的更多相关文章

  1. struts2拦截器的实现原理

    拦截器(interceptor)是Struts2最强大的特性之一,也可以说是struts2的核心,拦截器可以让你在Action和result被执行之前或之后进行一些处理.同时,拦截器也可以让你将通用的 ...

  2. struts2拦截器的实现原理及源码剖析

    拦截器(interceptor)是Struts2最强大的特性之一,也可以说是struts2的核心,拦截器可以让你在Action和result被执行之前或之后进行一些处理.同时,拦截器也可以让你将通用的 ...

  3. Okhttp拦截器统一异常处理并多次读取response.body().string()

    参考:https://blog.csdn.net/a624806998/article/details/73863606 引言: 写这篇文章,因为在自己编写实现Http日志拦截器的时候,在拦截器中使用 ...

  4. 从网络请求过程看OkHttp拦截器

    前言 之前我们结合设计模式简单说了下OkHttp的大体流程,今天就继续说说它的核心部分--拦截器. 因为拦截器组成的链其实是完成了网络通信的整个流程,所以我们今天就从这个角度说说各拦截器的功能. 首先 ...

  5. Java拦截器的实现原理

    对于某个类的A方法进行拦截,在A执行前插入一段代码,A执行后也插入一段代码 原理: 写个拦截器,拦截器中包含要插入前后执行的两段代码 interceptor { C();//C方法 D();//D方法 ...

  6. mybatis源码分析(5)-----拦截器的实现原理(动态代理+责任链)

    写在前面 MyBatsi 的拦截器模式是基于代理的代理模式.并且myBatis 的插件开发也是以拦截器的形式集成到myBatis 当中. MyBatis 的拦截器已经插件是在org.apache.ib ...

  7. Struts2_day04--课程介绍_Struts2拦截器概述&底层原理_重要的概念

    Struts2_day04 上节内容 今天内容 Struts2拦截器概述 拦截器底层原理 重要的概念 自定义拦截器 自定义登录拦截器 Struts2的标签库 Struts2表单标签(会用) Strut ...

  8. Android 开发 框架系列 OkHttp拦截器

    前言 此篇博客只讲解okhttp的拦截器功能的详细使用,如果你还不太了解okhttp可以参考我另外一篇博客 Android 开发 框架系列 OkHttp使用详解 添加Interceptor的简单例子 ...

  9. Spring 拦截器实现+后台原理(MethodInterceptor)

    MethodInterceptor MethodInterceptor是AOP项目中的拦截器(注:不是动态代理拦截器),区别与HandlerInterceptor拦截目标时请求,它拦截的目标是方法. ...

随机推荐

  1. go语言之进阶篇结构体指针类型匿名字段

    1.结构体指针类型匿名字段 示例: package main import "fmt" type Person struct { name string //名字 sex byte ...

  2. 游戏服务器框架:Leaf/go

    Leaf 是一个使用 Go 语言开发的开源游戏服务器框架,注重运行效率并追求极致的开发效率.Leaf 适用于几乎所有的游戏类型.其主要的特性: 良好的使用体验.Leaf 总是尽可能的提供简洁和易用的接 ...

  3. Gson解析复杂Json数据

    背景                                                                   json是一种数据格式,便于数据传输.存储.交换. gson是 ...

  4. CKEditor && CKFinder 配置

    准备                                                                                                   ...

  5. [CSS] Pseduo

    #self aside li{ list-style-type: none;padding:5px;border-bottom: 1px solid #ccc;} #self aside li:las ...

  6. 【Javascript Demo】防止按钮在短时间内被多次点击

    如果一个按钮可以在短时间内多次点击,那么有可能会被用户恶意点击,为防止这种情况,可以设定一定时间内只能点击一次,其他时间禁止点击按钮. 1.效果如下:     2.代码如下:   <div> ...

  7. oracle client字符集设置 乱码问题

    程序员经常要连接数据库   下面 就说一下 oracle数据库 客户端与服务器端 字符集一致性的问题   这可以解决中文乱码,其他字符乱码问题   主要是指在sqlplus中,其他类似toad/pls ...

  8. 如何使用FLASHGOT下载网页FLASH

    1 注意火狐的广告屏蔽插件可能将一些有用的东西屏蔽掉,从而无法得到广告FLASH, 2 随后即可在桌面上找到所需文件 你也可以按住A/T并单击FLASH文件(不论鼠标是否被替换为其他图形)迅雷会自动探 ...

  9. Visual Studio 2008破解90天试用期

    Visual Studio 2008破解90天试用期变成正式版的方法: 第一种方法(安装前用): 把iso文件中的setup文件夹中的setup.sdb文件中的[Product Key]下的一行的原来 ...

  10. 安装apache+php记录

    安装apache yum install httpd 修改apache配置文件,可以修改apache的默认端口号,根目录等 /etc/httpd/conf/httpd.conf 启动/重启apache ...