使用Spring Cloud Feign作为HTTP客户端调用远程HTTP服务的方法(推荐)

作者:司青 时间:2022-11-09 11:40:37 

在Spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端。我们可以使用JDK原生的URLConnection、Apache的Http Client、Netty的异步HTTP Client, Spring的RestTemplate。但是,用起来最方便、最优雅的还是要属Feign了。

Feign简介

Feign是一种声明式、模板化的HTTP客户端。在Spring Cloud中使用Feign, 我们可以做到使用HTTP请求远程服务时能与调用本地方法一样的编码体验,开发者完全感知不到这是远程方法,更感知不到这是个HTTP请求。比如:


@Autowired
private AdvertGropRemoteService service; // 远程服务
public AdvertGroupVO foo(Integer groupId) {
return service.findByGroupId(groupId); // 通过HTTP调用远程服务
}

开发者通过service.findByGroupId()就能完成发送HTTP请求和解码HTTP返回结果并封装成对象的过程。

Feign的定义

为了让Feign知道在调用方法时应该向哪个地址发请求以及请求需要带哪些参数,我们需要定义一个接口:


@FeignClient(name = "ea") // [A]
public interface AdvertGroupRemoteService {
@RequestMapping(value = "/group/{groupId}", method = RequestMethod.GET) // [B]
AdvertGroupVO findByGroupId(@PathVariable("groupId") Integer adGroupId) // [C]
@RequestMapping(value = "/group/{groupId}", method = RequestMethod.PUT)
void update(@PathVariable("groupId") Integer groupId, @RequestParam("groupName") String groupName)

A: @FeignClient用于通知Feign组件对该接口进行代理(不需要编写接口实现),使用者可直接通过@Autowired注入。

B: @RequestMapping表示在调用该方法时需要向/group/{groupId}发送GET请求。

C: @PathVariable与SpringMVC中对应注解含义相同。

Spring Cloud应用在启动时,Feign会扫描标有@FeignClient注解的接口,生成代理,并注册到Spring容器中。生成代理时Feign会为每个接口方法创建一个RequetTemplate对象,该对象封装了HTTP请求需要的全部信息,请求参数名、请求方法等信息都是在这个过程中确定的,Feign的模板化就体现在这里。

在本例中,我们将Feign与Eureka和Ribbon组合使用,@FeignClient(name = "ea")意为通知Feign在调用该接口方法时要向Eureka中查询名为ea的服务,从而得到服务URL。

Feign的Encoder、Decoder和ErrorDecoder

Feign将方法签名中方法参数对象序列化为请求参数放到HTTP请求中的过程,是由编码器(Encoder)完成的。同理,将HTTP响应数据反序列化为java对象是由解码器(Decoder)完成的。

默认情况下,Feign会将标有@RequestParam注解的参数转换成字符串添加到URL中,将没有注解的参数通过Jackson转换成json放到请求体中。注意,如果在@RequetMapping中的method将请求方式指定为POST,那么所有未标注解的参数将会被忽略,例如:


@RequestMapping(value = "/group/{groupId}", method = RequestMethod.GET)
void update(@PathVariable("groupId") Integer groupId, @RequestParam("groupName") String groupName, DataObject obj);

此时因为声明的是GET请求没有请求体,所以obj参数就会被忽略。

在Spring Cloud环境下,Feign的Encoder*只会用来编码没有添加注解的参数*。如果你自定义了Encoder, 那么只有在编码obj参数时才会调用你的Encoder。对于Decoder, 默认会委托给SpringMVC中的MappingJackson2HttpMessageConverter类进行解码。只有当状态码不在200 ~ 300之间时ErrorDecoder才会被调用。ErrorDecoder的作用是可以根据HTTP响应信息返回一个异常,该异常可以在调用Feign接口的地方被捕获到。我们目前就通过ErrorDecoder来使Feign接口抛出业务异常以供调用者处理。

Feign的HTTP Client

Feign在默认情况下使用的是JDK原生的URLConnection发送HTTP请求,没有连接池,但是对每个地址会保持一个长连接,即利用HTTP的persistence connection 。我们可以用Apache的HTTP Client替换Feign原始的http client, 从而获取连接池、超时时间等与性能息息相关的控制能力。Spring Cloud从Brixtion.SR5版本开始支持这种替换,首先在项目中声明Apache HTTP Client和feign-httpclient依赖:


<!-- 使用Apache HttpClient替换Feign原生httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>com.netflix.feign</groupId>
<artifactId>feign-httpclient</artifactId>
<version>${feign-httpclient}</version>
</dependency>

然后在application.properties中添加:


feign.httpclient.enabled=true

总结

通过Feign, 我们能把HTTP远程调用对开发者完全透明,得到与调用本地方法一致的编码体验。这一点与阿里Dubbo中暴露远程服务的方式类似,区别在于Dubbo是基于私有二进制协议,而Feign本质上还是个HTTP客户端。如果是在用Spring Cloud Netflix搭建微服务,那么Feign无疑是最佳选择。

以上所述是小编给大家介绍的使用Spring Cloud Feign作为HTTP客户端调用远程HTTP服务的方法(推荐)网站的支持!

来源:http://blog.csdn.net/neosmith/article/details/52449921

标签:spring,cloud,feign
0
投稿

猜你喜欢

  • Android Jni的简单使用详解

    2023-10-20 14:37:43
  • Mybatis实现单个和批量定义别名typeAliases

    2023-02-11 06:27:03
  • Java web项目中的强制登录功能实现代码

    2023-09-14 08:26:18
  • IDEA2022中部署Tomcat Web项目的流程分析

    2023-02-26 17:19:09
  • Java 反转带头结点的单链表并显示输出的实现过程

    2022-06-08 18:34:39
  • java操作mongodb示例分享

    2023-09-07 19:00:02
  • Java反射机制详解

    2023-05-20 11:09:47
  • Compose 的 Navigation组件使用示例详解

    2023-02-12 12:43:43
  • Android开发之设置开机自动启动的几种方法

    2021-12-04 20:35:37
  • 基于SpringBoot生成二维码的几种实现方式

    2022-02-27 16:24:31
  • Java数据结构之并查集的实现

    2023-06-29 06:58:32
  • SpringBoot RestTemplate 简单包装解析

    2023-02-01 17:02:55
  • VS2019编写C程序或者CUDA程序出现“无法启动程序,系统找不到指定的文件”问题的详细解决方法

    2022-04-25 08:09:31
  • Android中butterknife的使用与自动化查找组件插件详解

    2021-09-18 06:58:36
  • 全面总结java IO体系

    2023-05-16 13:19:12
  • C语言二叉树常见操作详解【前序,中序,后序,层次遍历及非递归查找,统计个数,比较,求深度】

    2021-09-30 08:41:23
  • Android中js和原生交互的示例代码

    2022-12-25 16:04:57
  • Android编程之在SD卡上进行文件读写操作实例详解

    2022-04-15 10:29:50
  • Java日常练习题,每天进步一点点(63)

    2021-10-22 12:35:44
  • C# Dynamic关键字之:解析dynamic就是Object

    2022-09-16 15:08:16
  • asp之家 软件编程 m.aspxhome.com