SpringCloud之Feign架构及原理解析

标签: SpringCloud

feign架构原理解析
目录
feign与ribbon对接的关键点
feign与ribbon对接主要还是在Client对象上做文章,将Client替换为继承Ribbon模板的实现类,这样就可以对执行请求前后做一些负载逻辑
什么是feign?
在使用feign之前,我们怎么发送请求?
有了feign之后我们怎么发送请求
spring cloud openfeign的加载过程
feign的REST Client API思想
JAX-RS标准
JAX-RS2.0 之 REST Client API
jersey
jersey 之 REST Client API
feign与JAX-RS2.0
feign代理的执行流程和关键对象
MethodHandler的关键对象和执行请求的流程
spring cloud openfeign的配置
配置的优先级顺序
properties和spring bean可以配置的内容
feign与ribbon对接的关键点
返回目录
什么是feign?
来自官网的解释:Feign makes writing java http clients easier
有了feign之后我们怎么发送请求
在这里插入图片描述
@FeignClient(value = “FooBarService”, configuration = FooBarServiceFeignConfiguration.class)
public interface FooBarService {
@RequestMapping(value = “/foo”, method = RequestMethod.GET)
String foo(@RequestParam(value = “param1”) String param1);

@RequestMapping(value = "/bar", method = RequestMethod.POST)
String bar(@RequestParam(value = "param1") String param1, @RequestParam(value = "param2") String param2);

}
@Autowired
FooBarService fooBarService;
public String foo() {
return fooBarService.foo(“rt”);
}
几行代码就能搞定,很大程度的节省了工作量,而且客户端和服务端关于接口的定义只需要写一次
具体的利弊我们这里就不做分析,在微服务盛行的现在,服务之间的调用单纯使用http client的场景已经基本不存在
返回目录
spring cloud openfeign的加载过程
上面的代码为什么接口没有实现类也可以使用,是不是跟mybatis一样使用了代理?

没错,接口最后都会生成代理实现
![在这里插入图片描述](https://img-blog.csdnimg.cn/2020031816473055.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzNjE0NDk4,size_16,color_FFFFFF,t_70
spring cloud openfeign关于代理的生成过程
在这里插入图片描述
feign的REST Client API思想
返回目录
JAX-RS标准
最新的REST接口标准为JAX-RS2.0,但是标准是供参考不能拿来直接吃的,具体还是要通过实现了标准的中间件来进行使用
JAX-RS2.0 之 REST Client API
摘自《Java RESTful Web Service实战(第2版)》
为什么JAX-RS2.0这么去抽象,我们这里暂不深入去思考,先拿来主义
jersey
jersey是JAX-RS标准的参考实现,是Java领域中最纯正的REST服务开发框架,例如eureka也是使用jersey来做REST接口和客户端发送请求,详见《服务发现之eureka》
jersey 之 REST Client API
官方文档:
ClientConfig clientConfig = new ClientConfig();
clientConfig.register(MyClientResponseFilter.class);
clientConfig.register(new AnotherClientFilter());

Client client = ClientBuilder.newClient(clientConfig);
client.register(ThirdClientFilter.class);

WebTarget webTarget = client.target(“http://example.com/rest”);
webTarget.register(FilterForExampleCom.class);
WebTarget resourceWebTarget = webTarget.path(“resource”);
WebTarget helloworldWebTarget = resourceWebTarget.path(“helloworld”);
WebTarget helloworldWebTargetWithQueryParam =
helloworldWebTarget.queryParam(“greeting”, “Hi World!”);

Invocation.Builder invocationBuilder =
helloworldWebTargetWithQueryParam.request(MediaType.TEXT_PLAIN_TYPE);
invocationBuilder.header(“some-header”, “true”);

Response response = invocationBuilder.get();
System.out.println(response.getStatus());
System.out.println(response.readEntity(String.class));
feign与JAX-RS2.0
feign主要是作为客户端发送请求,所以也是参考对照了JAX-RS2.0标准
feign并不是REST Client,只是参考了REST Client的实现,具体的目标还是为了更简单的实现http client请求
feign中怎么进行对应呢?
为什么这么去抽象我们这里也暂不深入研究(更深层的JAX-RS为什么这么抽象还未探明)
feign代理的执行流程和关键对象
代理生成时用到了什么组件、代理执行时用到了什么组件?
上文我们知道,所有请求最后都交给了MethodHandler来执行,所以我们重点关注MethodHandler即可
在这里插入图片描述
MethodHandler的关键对象和执行请求的流程
在这里插入图片描述1.RequestTemplate.Factory

创建RequestTemplate的工厂,包含MethodMetadata和Encoder对象

其中MethodMetadata是应用初始化时Contract解析@RequestMapping @RequestParam等注解而来的中间数据

2.Encoder

报文压缩gzip等

3.RequestInterceptor

为请求附加一些信息,类似spring mvc的interceptor拦截器

4.Target

主要是把@FeignClient里的url拼接到RequestTemplate

5.Options

用于请求的参数配置

6.Decoder

解析返回报文,如果返回404,判断decode404==true则解析,否则交给ErrorDecoder解析

7.ErrorDecoder

请求错误处理

8.Logger.Level

日志等级,包含四种 none basic headers full

9.Logger

对应的配置为LoggerFactory,记录日志用

10.Retryer

重试,DefaultRetryer默认会重试5次

11.Client

真正执行http请求的客户端,可以配置,默认由FeignRibbonClientAutoConfiguration进行配置结合ribbon使用
spring cloud openfeign的配置
配置的优先级顺序
在这里插入图片描述properties和spring bean可以配置的内容
主要还是配置我们上面feign的关键对象,properties和spring bean可配置的:
在这里插入图片描述
同ribbon一样,spring-cloud-openfeign的配置也是懒加载,每个feignclient都可以有自己个性化的配置,且配置是懒加载的,但是为每个接口生成代理的时候已经去注册和使用了相关的配置,其实懒加载没有用了。

所以只实现了最终目的:每个feignclient 都可以有自己个性化的配置

这里的FeignContext跟ribbon的SpringClientFactory同理

public class FeignContext extends NamedContextFactory {
public FeignContext() {
super(FeignClientsConfiguration.class, “feign”, “feign.client.name”);
}
}

版权声明:本文为qq_43614498原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_43614498/article/details/104947626

智能推荐

1638 统计只差一个字符的子串数目(动态规划)

1. 问题描述: 给你两个字符串 s 和 t ,请你找出 s 中的非空子串的数目,这些子串满足替换一个不同字符以后,是 t 串的子串。换言之,请你找到 s 和 t 串中恰好只有一个字符不同的子字符串对的数目。比方说, "computer" 和 "computation"...

websocket基本原理

HTTP中一个request只能有一个response。而且这个response也是被动的,不能主动发起 因此过去的服务端推送信息是通过客户端不停的轮询实现的 websocket是双向通信协议,提供了服务端主动推送信息的能力 需要客户端(浏览器)和服务端同时支持 如果经过代理的话,还需要代理支持,否则有些代理在长时间无通信时会自动切断连接 因此WS为了保证连接不被断掉,会发心跳 WebSocket...

mybatis+ehcache二级缓存

导入jar包 mapper.xml文件开启二级缓存 pojo类实现序列化接口 配置ehcache.xml 测试...

python+opencv实现图像拼接

任务 拍摄两张图片去除相同部分,拼接在一起 原图 结果 步骤 读取两张图片 使用sift检测关键点及描述因子 匹配关键点 处理并保存关键点 得到变换矩阵 图像变换并拼接 代码实现 扩展 这里对右边图像进行变换,右边变得模糊,可以修改代码对左边图像变换 这里只有两张图片拼接,可以封装实现多张图片拼接 可以修改代码实现上下图片的拼接...

python_sklearn机器学习算法系列之AdaBoost------人脸识别(PCA,决策树)

          注:在读本文之前建议读一下之前的一片文章python_sklearn机器学习算法系列之PCA(主成分分析)------人脸识别(k-NearestNeighbor,KNN)         本文主要目的是通过一个简单的小...

猜你喜欢

memmove函数与memcpy函数的模拟实现

memmove函数和memcpy函数都是在内存复制任意类型的,但是它俩也有区别。当源区域和目标区域有重复的,memmove函数会复制缓冲区重叠的部分,而memcpy相反,会报出未知错误。 下面给出两个函数的实现 首先,memmove函数。 实现的基本原理如下图。 具体代码如下: memcpy函数的实现很简单,就直接给出源代码了...

SpringFramework核心 - IOC容器的实现 - 总结

1. 概述 把Spring技术内幕第一章和第二章过了一遍,也做了一些笔记, 对IOC容器的实现有了一定皮毛理解,现在跟着源码再过一遍总结一下IOC容器的初始化,Bean的初始化的过程,做一下总结 ① IOC容器和简单工厂模式 在开始之前,先想想我们平时是怎么使用IOC容器为我们管理Bean的,假设我们要把下面的User类交给IOC容器管理 我们不想关心如何创建一个User对象实例的,仅仅在需要他的...

Python和Django的安装

个人博客导航页(点击右侧链接即可打开个人博客):大牛带你入门技术栈  一、下载并安装Python Python 官方下载地址:http://www.python.org/ftp/python/ 我们这里选择的是 Python 2.7.2 。虽然目前最新版是Python 3.2.2, 但是Django目前还不支持 Python 3.2.2。 安装步骤很简单,双击安装包开...

OpenStack代码贡献初体验

为什么80%的码农都做不了架构师?>>>     OpenStack如今已成为开源云平台中的明星项目,得到广泛关注。OpenStack的优秀出众依赖于众多开发者的努力,在享受其带来的便利与快捷的同时,为其做一份贡献也是一个开发者的义务。  在前段时间的OpenStack的测试过程中,我发现Nova项目中的一个Bug,于是向社区提交了Bug报...