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客户端的创建。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值