Spring Boot 2.1.x Spring Cloud Greenwich.SRx
一、Feign Contract 作用
1.1、基于 spring boot 如何编写 Feign 调用
Spring Boot + Feign 是远程 RPC 的一种实现方案,通常在代码中,定义一个远程API会采用接口的方式,使用 Spring MVC
的方式定义一个远程调用,如:使用对应的 annotation ,@RequestParam
、@RequestBody
等。
学习成本低,编写风格也和编写 Spring Mvc 接口一致,很简单就定义了相关的远程 RPC 调用接口。
1.2、Feign contract 作用
《Feign如何进行服务间请求调用#Feign Clietn 调用流程》中讨论 Feign 进行服务间调用的本质就是拼接 RequestTemplate 对象,发起 HTTP 请求。
拼接 HTTP 请求通常会涉及到几个问题点:
- 1、常见的 POST 还是 GET ,或者 DELETE 等请求方法
- 2、参数存放到表单,还是使用 JSON 字符串
- 3、请求 URL 定义
再来对照一下平时写代码时关于 Feign 接口的定义:
通过代码,能够想象得到,通过解析接口(标记了 @FeignClient 标识的接口)方法上的相关注解定义就能够得到拼接 HTTP 请求所需的参数
- 如:
@RequestMapping
定义的 POST 方法 - 如:
@RequestMapping
定义的资源访问路径 - 如:方法参数上
@RequestBody
定义了传输方式使用的 JSON 字符串格式
在 Feign 代码中完成该项工作的是 feign.Contract
二、关于 Contract 的实现
Spring Boot 集成 Feign + Hystrix 后相关实现
2.1、Contract 接口定义
根据 Contract
源码及注释能够得到
- Contract 定义了
Contract#parseAndValidatateMetadata
方法用来解析 Feign 接口从而得到 Http 请求所需相关参数 通过 Contract 能够定义不同Feign 接口解析方案
2.2、BaseContract 模板抽象类
BaseContract
是Contract
模板抽象实现,BaseContract
定义了关于Feign
接口的基础模板流程接口格式校验
- 解析 Feign 接口标注的 Annotation ,然后构建
MethodMetadata
对象存储相关数据。
其中具体的解析方法作为模板方法,需要对应的子类自行实现,对应的解析操作有
- 类注解解析(
BaseContract#processAnnotationOnClass
) - 方法注解解析(
BaseContract#processAnnotationOnMethod
) - 方法参数注解解析(
BaseContract#processAnnotationsOnParameter
)
2.2.1、Default 继承模板抽象类 BaseContract
feign.Default
继承了模板抽象类 BaseContract
,同时实现了三个解析方法
- 类注解解析(
Default #processAnnotationOnClass
) - 方法注解解析(
Default #processAnnotationOnMethod
) - 方法参数注解解析(
Default #processAnnotationsOnParameter
)
feign.Default
是 open feign 官方模式实现,主要解析的注解有
对应相关源码如下
类注解解析
方法注解解析
方法参数注解解析
2.2.1、SpringMvcContract 继承模板抽象类 BaseContract
SpringMvcContract
是 Spring Cloud 集成 Open Feign 后,针对 Spring MVC 代码编写风格而特定的解析类,通过该类,用户可以直接使用 Spring MVC 的编码风格编写 Feign RPC 调用代码。
同样的 SpringMvcContract
继承自了模板抽象类 BaseContract
,主要的实现同样是三个解析方法的实现
类注解解析
方法注解解析
方法参数解析
针对不同类型的方法参数提供不同解析器
PathVariableParameterProcessor
针对 URL 入参的解析QueryMapParameterProcessor
针对@SpringQueryMap
入参注解解析RequestHeaderParameterProcessor
针对@RequestHeader
入参注解解析RequestParamParameterProcessor
针对@RequestParam
入参注解解析
2.3、HystrixDelegatingContract
feign 集成 Hystrix 后,请求会被 HystrixCommand
代理,对应的返回值也不再是编码时方法的返回值,,HystrixDelegatingContract
类新增了对返回类型的解析处理。
相关源码如下
从代码能够知道HystrixDelegatingContract
采用装饰模式,对已有的 Contract
增强集成 Hystrix 而导致返回值无法正确解析的解析处理。
在 Spring Boot 集成项目中,被装饰的对象实例通常为
SpringMvcContract