RestTemplate源码解读
引言
SpringCloud的微服务均是以Http接口的形式来暴露自身服务的,因此在调用远程服务的时候必须使用HTTP客户端,可选的方案有JDK原生的URL Connection、Apache的Http Client、Netty的异步Http Client,Spring的RestTemplate和Fegin。
今天主要介绍一下Spring的RestTemplate。
源码跟读
通过源码可以看到RestTemplate进行请求的很多方法最终调用的均是doExecute方法。
可以看出,主要分为创建请求Request,执行请求Request,处理返回结果response3个步骤。
创建请求
跟进createRequest()方法,发现该方法是由HttpAccessor负责实现的。
其基本思路是传入请求地址url和请求方法method,然后由ClientHttpRequestFactory工厂负责Request的创建,ClientHttpRequestFactory为一个接口,其实现类主要有:
HttpAccessor提供了get/set方法,方便传入不同的ClientHttpRequestFactory实现类,如果需要自定义ClientHttpRequestFactory工厂,直接implements ClientHttpRequestFactory复写方法,然后注入HttpAccessor即可。
HttpAccessor默认使用的是SimpleClientHttpRequestFactory工厂实现类。
继续跟进SimpleClientHttpRequestFactory工厂实现类。
它提供了两种请求创建方法,分别支持同步和异步请求:
- createRequest(URI uri, HttpMethod httpMethod)
- createAsyncRequest(URI uri, HttpMethod httpMethod)
上述两种方法均包括打开连接、准备连接、创建连接3个步骤。
先看openConnection方法,它的实现比较简单,有代理Proxy存在,则传入Proxy打开连接,否则则直接通过URL打来连接。
prepareConnection方法主要根据传入的参数,进行连接前的一些配置工作,比如设置连接超时、读取超时、根据不同请求method设置相应配置参数等。
最后创建连接的时候,根据bufferRequestBody是否为True,创建2种不同的连接,分别为批处理连接和流处理连接。
return (ClientHttpRequest)(this.bufferRequestBody ? new SimpleBufferingClientHttpRequest(connection, this.outputStreaming) : new SimpleStreamingClientHttpRequest(connection, this.chunkSize, this.outputStreaming));
执行请求
切回到RestTemplate类的doExecute方法,可以看到建立http连接,拿到ClientHttpRequest后,执行请求的方法为execute()。
ClientHttpRequest为接口,仅有一个execute()方法,看一下ClientHttpRequest的实现类:
其中用的比较多的是AbstractClientHttpRequest抽象类,SimpleStreamingClientHttpRequest和SimpleBufferingClientHttpRequest分别继承了AbstractClientHttpRequest,复写某些方法以支持流/批处理请求。
跟进AbstractClientHttpRequest抽象类的execute()方法,
execute()内部调用的是executeInternal(),由子类来具体实现,可以看一下SimpleBufferingClientHttpRequest的方法实现,其他子类实现方式大同小异。
可以看到,主要是做了一些添加请求头、返回设置等的操作,最后得到请求的返回类SimpleClientHttpResponse。
至此,我们就拿到请求的返回了,下一步就是处理返回结果了。
处理返回结果
返回结果处理主要分为两步:
- handleResponse(url, method, response)
- responseExtractor.extractData(response)
其中,handleResponse(url, method, response)主要负责对请求的异常进行处理。
可以看到,handleResponse()方法首先获取请求错误的处理器errorHandler,然后把response交给它进行后续的处理。
而responseExtractor.extractData(response)主要负责返回数据的解析。
responseExtractor为接口,其实现类为:
其中ResponseEntityResponseExtractor和HeadersExtractor为RestTemplate的内部类,主要处理返回的headers和entity,我们重点关注返回消息的转化处理类HttpMessageConverterExtractor。
可以看到,extractData先将response交给responseWrapper,如果responseWrapper有消息体且非空,则进行返回消息的读取操作。
消息的读取需要借助HttpMessageConverter接口,HttpMessageConverter具有多种实现类,以完成不同格式消息的读取,相当于消息解码器或转换头。
可以看到,在构建HttpMessageConverterExtractor实例的时候,需要传入HttpMessageConverter的接口集合messageConverters,用于对不同返回格式消息的读取。
首先,得到messageConverters的迭代器,然后遍历迭代器,依次执行不同HttpMessageConverter读取操作,最终完成返回消息体的读取操作。
迭代过程中,如果当前MessageConverter属于GenericHttpMessageConverter的接口实现,则执行:
return genericMessageConverter.read(this.responseType, (Class)null, responseWrapper);
否则:
return messageConverter.read(this.responseClass, responseWrapper);
总结
RestTemplate是Spring提供的用于访问Rest服务的客户端;
RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率;
调用RestTemplate的默认构造函数,RestTemplate对象在底层通过使用java.net包下的实现创建HTTP请求;
可以通过使用ClientHttpRequestFactory指定不同的HTTP请求方式;
在设计模式上,主要通过工厂模式来完成各类Http客户端的创建。
欢迎您扫一扫上面的二维码,关注我的微信公众号!
RestTemplate源码解读相关推荐
- Bert系列(二)——源码解读之模型主体
本篇文章主要是解读模型主体代码modeling.py.在阅读这篇文章之前希望读者们对bert的相关理论有一定的了解,尤其是transformer的结构原理,网上的资料很多,本文内容对原理部分就不做过多 ...
- Bert系列(三)——源码解读之Pre-train
https://www.jianshu.com/p/22e462f01d8c pre-train是迁移学习的基础,虽然Google已经发布了各种预训练好的模型,而且因为资源消耗巨大,自己再预训练也不现 ...
- linux下free源码,linux命令free源码解读:Procps free.c
linux命令free源码解读 linux命令free源码解读:Procps free.c 作者:isayme 发布时间:September 26, 2011 分类:Linux 我们讨论的是linux ...
- nodeJS之eventproxy源码解读
1.源码缩影 !(function (name, definition) { var hasDefine = typeof define === 'function', //检查上下文环境是否为AMD ...
- PyTorch 源码解读之即时编译篇
点击上方"AI遇见机器学习",选择"星标"公众号 重磅干货,第一时间送达 作者丨OpenMMLab 来源丨https://zhuanlan.zhihu.com/ ...
- Alamofire源码解读系列(九)之响应封装(Response)
本篇主要带来Alamofire中Response的解读 前言 在每篇文章的前言部分,我都会把我认为的本篇最重要的内容提前讲一下.我更想同大家分享这些顶级框架在设计和编码层次究竟有哪些过人的地方?当然, ...
- Feflow 源码解读
Feflow 源码解读 Feflow(Front-end flow)是腾讯IVWEB团队的前端工程化解决方案,致力于改善多类型项目的开发流程中的规范和非业务相关的问题,可以让开发者将绝大部分精力集中在 ...
- spring-session源码解读 sesion
2019独角兽企业重金招聘Python工程师标准>>> spring-session源码解读 sesion 博客分类: java spring 摘要: session通用策略 Ses ...
- 前端日报-20160527-underscore 源码解读
underscore 源码解读 API文档浏览器 JavaScript 中加号操作符细节 抛弃 jQuery,拥抱原生 JS 从 0 开始学习 GitHub 系列之「加入 GitHub」 js实现克隆 ...
- php service locator,Yii源码解读-服务定位器(ServiceLocator)
SL的目的也是解耦,并且非常适合基于服务和组件的应用. Service Locator充当了一个运行时的链接器的角色,可以在运行时动态地修改一个类所要选用的服务, 而不必对类作任何的修改. 一个类可以 ...
最新文章
- Python基础--文件操作
- codeforces193B
- sdwan解决方案的分类—Vecloud
- java plt_matplotlib 画动态图以及plt.ion()和plt.ioff()的使用详解
- 什么是网络光端机?网络光端机工作原理及功能介绍!
- 图:图的邻接矩阵创建、深度优先遍历和广度优先遍历详解
- Bootstrap3 面板的情景类
- oracle ssl jdbc 架构,我与数据库的JDBC连接是否使用SSL?
- python 数组中取出最小值_Python 数组中的冒号使用
- pytorch搭建LSTM神经网络预测电力负荷
- python安装caffe_caffe中安装python
- 【学习笔记】SAP资产模块
- 0723电话面试整理
- UIPath 获取网页元素做遍历点击的实现
- 《人性的弱点全集》- [美]戴尔·卡耐基/著
- 免费开源好用还佛系的国产PDF软件:pdf补丁丁下载 | 含pdf补丁丁使用手册
- 描写火车站场景_形容车站人多的句子(车站场景写一段话)
- Qt 事件过滤器(秒懂)
- 阿里云ACP云计算工程师认证攻略--转载
- 流量控制组件, 技术选型:Sentinel vs Hystrix