Feign 系列(02)Why Feign

1. 什么是 Feign

Feign 的英文表意为“假装,伪装,变形”, 是一个 Http 请求调用的轻量级框架,可以以 Java 接口注解的方式调用 Http 请求,而不用像 Java 中通过封装 HTTP 请求报文的方式直接调用。

Feign 通过处理注解,将请求模板化,当实际调用的时候,传入参数,根据参数再应用到请求上,进而转化成真正的请求,这种请求相对而言比较直观。

Feign 被广泛应用在 Spring Cloud 的解决方案中,是学习基于 Spring Cloud 微服务架构不可或缺的重要组件。

Feign 开源项目地址:https://github.com/OpenFeign/feign

2. Feign 解决了什么问题

Feign 封装 HTTP 调用流程,面向接口编程。

Feign 本身很简单,但做了大量的适配工作,这也是这个框架存在的意义。

在服务调用的场景中,我们经常调用基于 Http 协议的服务,而我们经常使用到的框架可能有HttpURLConnection、Apache HttpComponnets、OkHttp3 、Netty 等等,这些框架在基于自身的专注点提供了自身特性。而从角色划分上来看,他们的职能是一致的提供 Http 调用服务。具体流程如下:

图1:Http请求调用过程分析

sequenceDiagram
客户端 ->> Client框架: 构建请求行(url)
客户端 ->> Client框架: 构建请求头(Header)
客户端 ->> Client框架: 构建请求体(body)
Client框架 ->> 服务端: 发送Http请求
Note right of 服务端: 服务端处理请求<br/>

服务端 -->> Client框架: 返回报文
Client框架 -->> 客户端: 提取报文信息,解析成JavaBean
Note left of 客户端: 客户端处理业务

总结: 根据上图的分析可知:要实现 Feign 客户端,主要是将 Method 方法的参数解析成 Http 请求的请求行、请求行、请求体,然后使用 HttpClient 发送请求。但问题:

  • 一是 REST 声明式规范有以下几种:Feign、JAX-RS 1/2、Spring Web MVC 都需要进行适配。这几种声明式注解的适配接口是 feign.Contract
  • 二是 Http 客户端有 JDK 自带的 HttpURLConnection、Apache HttpComponnets、OkHttp3 、Netty 等,需要适配。这几种客户端的适配接口是 feign.Client
  • 三是支持负载均衡与熔断。负载均衡 Ribbon 是对 feign.Client 进行包装。熔断 Hystrix 在 HystrixFeign 中自定义 InvocationHandlerFactory 的实现,创建 HystrixInvocationHandler,对 method.invoke 请求做拦截。
  • 四是各种编解码的适配,实现接口 feign.codec.Decoderfeign.codec.Encoder

2.1 REST 声明式规范

表1:Feign、JAX-RS 1/2、Spring Web MVC 声明式规范

REST框架 使用场景 请求映射注解 请求参数
JAX-RS 客户端声明、
服务端声明
@Path @*Param
Feign 客户端声明 @RequestLine @Param
Spring Web MVC 服务端声明 @ReqeustMapping @RequestParam

总结: 这几种规范,其中 Feign 已经适配了 JAX-RS 1/2 和 Feign 自带的注解规范。Spring Cloud Open Feign 进一步适配了 Spring Web MVC 的注解规范。

2.1.1 Feign(默认)

GitHub github = Feign.builder()
.decoder(new GsonDecoder())
.target(GitHub.class, "https://api.github.com");

2.1.2 JAX-RS

maven 依赖:feign-jaxrsfeign-jaxrs2

GitHub github = Feign.builder()
.contract(new JAXRSContract())
.target(GitHub.class, "https://api.github.com");

2.2 多Http客户端支持

2.2.1 OkHttp

maven 依赖:feign-okhttp

GitHub github = Feign.builder()
.client(new OkHttpClient())
.target(GitHub.class, "https://api.github.com");

2.3 负载均衡与熔断

2.3.1 Hystrix

maven 依赖:feign-hystrix

GitHub github = HystrixFeign.builder()
.target(GitHub.class, "https://myAppProd");

2.3.2 Ribbon

maven 依赖:feign-ribbon

GitHub github = Feign.builder()
.client(RibbonClient.create())
.target(GitHub.class, "https://myAppProd");

2.4 编解码器

2.4.1 Gson

maven 依赖:feign-gson

GitHub github = Feign.builder()
.encoder(new GsonEncoder())
.decoder(new GsonDecoder())
.target(GitHub.class, "https://api.github.com");

2.4.2 Jackson

maven 依赖:feign-jackson

GitHub github = Feign.builder()
.encoder(new JacksonEncoder())
.decoder(new JacksonDecoder())
.target(GitHub.class, "https://api.github.com");

2.4.3 JAXB

maven 依赖:feign-jaxb

 Api api = Feign.builder()
.encoder(new JAXBEncoder())
.decoder(new JAXBDecoder())
.target(Api.class, "https://apihost");

2.4.4 SOAP

maven 依赖:feign-soap

Api api = Feign.builder()
.encoder(new SOAPEncoder(jaxbFactory))
.decoder(new SOAPDecoder(jaxbFactory))
.errorDecoder(new SOAPErrorDecoder())
.target(MyApi.class, "http://api");

每天用心记录一点点。内容也许不重要,但习惯很重要!

Feign 系列(02)Why Feign的更多相关文章

  1. Feign 系列(05)Spring Cloud OpenFeign 源码解析

    Feign 系列(05)Spring Cloud OpenFeign 源码解析 [TOC] Spring Cloud 系列目录(https://www.cnblogs.com/binarylei/p/ ...

  2. Feign 系列(04)Contract 源码解析

    Feign 系列(04)Contract 源码解析 [TOC] Spring Cloud 系列目录(https://www.cnblogs.com/binarylei/p/11563952.html# ...

  3. Feign 系列(01)最简使用姿态

    目录 Feign 系列(01)最简使用姿态 1. 引入 maven 依赖 2. 基本用法 3. Feign 声明式注解 Feign 系列(01)最简使用姿态 Spring Cloud 系列目录(htt ...

  4. Feign 系列(03)Feign 工作原理

    目录 Feign 系列(03)Feign 工作原理 1. Feign 是如何设计的 2. Feign 动态代理 2.1 ReflectiveFeign 构建 2.2 生成代理对象 2.3 Method ...

  5. net core天马行空系列:移植Feign,结合Polly,实现回退,熔断,重试,超时,做最好用的声明式http服务调用端

    系列目录 1.net core天马行空系列:原生DI+AOP实现spring boot注解式编程 2.net core天马行空系列: 泛型仓储和声明式事物实现最优雅的crud操作 3.net core ...

  6. SpringCloud系列十三:Feign对继承、压缩、日志的支持以及构造多参数请求

    1. 回顾 上文讲解了手动创建Feign,比默认的使用更加灵活. 本文将讲解Feign对继承.压缩的支持以及日志和多参数请求的构造等. 2. Feign对继承的支持 Feign支持继承.使用继承,可将 ...

  7. Aoite 系列(02) - 超动感的 Ioc 容器

    Aoite 系列(02) - 超动感的 Ioc 容器 Aoite 是一个适于任何 .Net Framework 4.0+ 项目的快速开发整体解决方案.Aoite.Ioc 是一套解决依赖的最佳实践. 说 ...

  8. SAP接口编程 之 JCo3.0系列(02) : JCo Client Programming

    SAP接口编程 之 JCo3.0系列(02) : JCo Client Programming 字数545 阅读52 评论0 喜欢1 JCo3.0调用SAP函数的过程 大致可以总结为以下步骤: 连接至 ...

  9. Java 之 I/O 系列 02 ——序列化(二)

    Java 之 I/O 系列 目录 Java 之 I/O 系列 01 ——基础 Java 之 I/O 系列 02 ——序列化(一) Java 之 I/O 系列 02 ——序列化(二) 继续上篇的第二个问 ...

随机推荐

  1. 文件上传&&验证文件格式

    $(function(){ $(".layui-progress").hide(); $("[data-upload-file]").each(function ...

  2. DNS域名解析服务以及Bind服务程序

    一般来讲域名比IP地址更加的有含义.也更容易记住,所以通常用户更习惯输入域名来访问网络中的资源,但是计算机主机在互联网中只能通过IP识别对方主机,那么就需要DNS域名解析服务了. DNS域名解析服务( ...

  3. Java.util包教程

    java.util.ArrayDeque 类提供了可调整大小的阵列,并实现了Deque接口.以下是关于阵列双端队列的要点: 数组双端队列没有容量限制,使他们增长为必要支持使用. 它们不是线程安全的;如 ...

  4. Oracle查询最近执行过的SQL语句

    oracle 查询最近执行过的 SQL语句 select sql_text,last_load_time from v$sql order by last_load_time desc; SELECT ...

  5. Selenium3 + Python3自动化测试系列十二——窗口截图与关闭浏览器

    窗口截图 自动化用例是由程序去执行的,因此有时候打印的错误信息并不十分明确.如果在脚本执行出错的时候能对当前窗口截图保存,那么通过图片就可以非常直观地看出出错的原因.WebDriver提供了截图函数g ...

  6. Vue.js 入门:从零开始做一个极简 To-Do 应用

    Vue.js 入门:从零开始做一个极简 To-Do 应用 写作时间:2019-12-10版本信息:Vue.js 2.6.10官网文档:https://cn.vuejs.org/ 前言  学习 Vue ...

  7. How to easily Detect Objects with Deep Learning on Raspberry Pi

    https://medium.com/nanonets/how-to-easily-detect-objects-with-deep-learning-on-raspberrypi-225f29635 ...

  8. 4、服务注册&服务提供者

    1.什么是服务提供者 服务提供者(Service Provider):是指服务的被调用方(即:为其它服务提供服务的服务):服务提供者,作为一个Eureka Client,向Eureka Server做 ...

  9. KiCAD实用操作

    KiCAD实用操作之一:自动编辑线宽 今天偶然间发现的一个比较实用的功能,算是KiCAD的一个优点吧(或许是在AD上面没发现):当整个PCB布完线或者在布线过程中,我们有可能需要对某个线的宽度进行调整 ...

  10. 【模板篇】NTT和三模数NTT

    之前写过FFT的笔记. 我们知道FFT是在复数域上进行的变换. 而且经过数学家的证明, DFT是复数域上唯一满足循环卷积性质的变换. 而我们在OI中, 经常遇到对xxxx取模的题目, 这就启发我们可不 ...