SpringCloud Netflix Feign
服务调用有2种方式:REST、RPC,SpringCloud一般用RestTemplate来实现REST调用,
此外SpringCloud还可以使用Feign来调用服务,Feign是声明式的服务调用,所谓声明式就是通过服务接口来调用,和RPC相似。
REST使用HTTP协议,RPC使用TCP协议,Feign只是伪RPC调用,因为Feign底层使用的协议是HTTP。
Eureka、Ribbon、Feign都是Netflix旗下的项目,都被SpringCloud集成了。
此处写一个feign的demo,获取用户的所有订单,user-service调用order-service
服务消费者user-service
(1)创建时勾选Spring Cloud Routing -> OpenFeign,当然Eureka Client、Spring Web等等也要勾选,不用勾选Ribbon,Eureka Client中已经包含了Ribbon的依赖
也可以收手动加feign的依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
(2)引导类上加 @EnableFeignClients
(3)新建包feign用来存放feign服务调用的接口,包下新建接口OrderFeignService
@FeignClient("order-service") //参数指定要调用的服务名称。feign也内置了ribbon,会自动实现负载均衡
public interface OrderFeignService {
@GetMapping("/api/v1/order/list") //该服务要调用的地址,不需要使用RESTful风格
List<Order> findOrdersByUserId(@RequestHeader("user_id") Integer user_id); //使用参数表传递参数
}
一个要调用的服务对应一个接口,如果要调用多个服务,写多个接口。
使用参数表传递参数,每个参数前都要加注解。
启动应用时检测到引导类上有@EnableFeignClients,会扫描@FeignClient标注的接口,给该接口生成动态代理(使用RestTemplate来代理),放在Spring容器中。
调用服务时,底层还是使用RestTemplate来调用服务,使用的还是HTTP协议。
(4)controller
@Controller
@RequestMapping("/api/v1/user")
public class UserController {
//注入要调用的服务接口,实际是注入动态代理生成的RestTemplate
@Resource
private OrderFeignService orderFeignService;
//根据用户id查找用户所有订单
@GetMapping("/order/{user_id}")
@ResponseBody
public List<Order> findOrdersByUserId(@PathVariable Integer user_id){
//调用Feign客户端(接口)的方法,传入需要的参数
List<Order> orderList = orderFeignService.findOrdersByUserId(user_id);
return orderList;
} }
实际写代码时要在service层调用服务。
Feign比RestTemplate要麻烦些,底层还是调用RestTemplate,还要包装为代理对象,时间、资源开销都增加了;
一会儿用RESTful风格传参,一会@RequestHeader传参,不统一,如果要在被调者中使用RESTful风格,还需要再写一个方法映射为RESTful风格。
但把服务调用写成接口,使得服务调用也是面向接口编程的,消费者、提供者没有耦合在业务方法(类)中,使用接口对接降低了耦合;
升级时只需修改feign包下的feign接口,不必到处修改RestTemplate的调用,好维护,所以feign也很常用。
服务提供者
@Controller
@RequestMapping("/api/v1/order")
public class OrderController { //根据用户id查找该用户的所有订单
@GetMapping("/list") //请求方式、映射地址都要和消费者中的Feign接口对应
@ResponseBody
public List<Order> findAllByUserId(@RequestHeader("user_id") Integer user_id){ //参数表要和消费者中Feign接口中方法的参数表对应
//一些列操作
//......
return orderList;
} }
Feign有一个很不好地方的:传参方式不统一,消费者用@RequestHeader传参,提供者也要用这个来接收,难以统一使用RESTful
消费者使用@RequestHeader传,提供者只能使用@RequestHeader、@RequestParam来接收。
消费者使用@RequestBody传,提供者只能使用@RequestBody、@RequestParam来接收。
@RequestParam是通用的,请求头、请求体中的数据都可以接收。
一般地,少量数据比如int、String使用@RequestHeader传输,大量数据比如Map、User对象使用@RequestBody来传输。
使用@RequestBody时,映射方式要使用@PostMapping,不能使用@GetMapping,因为体积大,要使用post。
@RequestHeader是将数据绑定到请求头,使用Get方式传输,或者从请求头中获取数据;
@RequestBody是将数据绑定大请求体,使用Post方式传输,或者从请求体中获取数据。
@PathVariable是接收Restful风格的url中的参数。
Restful有个缺点:能传递的数据类型有限,毕竟要写在url中,不能是User之类的对象。
映射方式:
@RequestMapping可以接收、处理所有请求方式中的某一种,需使用method属性指定,不指定时默认为 RequestMethod.GET
@GetMapping只接收、处理GET方式的请求,是@RequestMapping(method=RequestMethod.GET)的简写
@PostMapping只接收、处理POST方式的请求,是@RequestMapping(method=RequestMethod.POST)的简写
@PutMapping
@DeleteMapping

SpringCloud Netflix Feign的更多相关文章
- SpringCloud学习笔记(六、SpringCloud Netflix Feign)
目录: feign简介 feign应用 feign简介: feign是一款Netflix开源的声明式.模板化的http客户端,它可以更加便捷.优雅的调用http api:SpringCloud对Net ...
- SpringCloud(5)---Feign服务调用
SpringCloud(5)---Feign服务调用 上一篇写了通过Ribbon进行服务调用,这篇其它都一样,唯一不一样的就是通过Feign进行服务调用. 注册中心和商品微服务不变,和上篇博客一样,具 ...
- 31.【微服务架构】SpringCloud之Feign(五)
Feign简介 Feign 是一个声明web服务客户端,这便得编写web服务客户端更容易,使用Feign 创建一个接口并对它进行注解,它具有可插拔的注解支持包括Feign注解与JAX-RS注解,Fei ...
- SpringCloud使用Feign实现服务间通信
SpringCloud的服务间通信主要有两种办法,一种是使用Spring自带的RestTemplate,另一种是使用Feign,这里主要介绍后者的通信方式. 整个实例一共用到了四个项目,一个Eurek ...
- SpringCloud之Feign负载均衡(四)
整合Feign pom.xml <dependency> <groupId>org.springframework.cloud</groupId> <arti ...
- Spring-Cloud之Feign声明式调用-4
一.Feign受Retrofit.JAXRS-2.0和WebSocket影响,采用了声明式API 接口的风格,将Java Http 客户端绑定到它的内部. Feign 首要目的是将 Java Http ...
- SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]
目录 前提:本篇是基于 SpringCloud+Eureka+Feign+Ribbon的简化搭建流程和CRUD练习[1] 的修改与拓展 1.修改consumer的CenterFeign.java,把返 ...
- SpringCloud实战-Feign声明式服务调用
在前面的文章中可以发现当我们通过RestTemplate调用其它服务的API时,所需要的参数须在请求的URL中进行拼接,如果参数少的话或许我们还可以忍受,一旦有多个参数的话,这时拼接请求字符串就会效率 ...
- SpringCloud使用Feign调用其他客户端带参数的接口,传入参数为null或报错status 405 reading IndexService#del(Integer);
SpringCloud使用Feign调用其他客户端带参数的接口,传入参数为null或报错status 405 reading IndexService#del(Integer); 第一种方法: 如果你 ...
随机推荐
- Gitee Git bash VSCode操作简易说明
GIT Git是一个分布式的版本控制系统,只是软件,需要你下载装到电脑上,实现git功能. Github.Gitee基于git的项目托管平台.Github是国外的,连接速度因人而异:另外Github收 ...
- Api跨域设置
跨域设置:(服务端) webconfig文件中,system.webServer节点下添加 <!--跨域请求:三个配置信息--> <httpProtocol> <cust ...
- java通过递归统计文件大小
思路就是通过文件的遍历,对一个文件夹中的非目录文件进行大小统计,并对其中目录文件进行相同的遍历操作,代码如下: package word; import java.io.File; import ja ...
- C#从委托、lambda表达式到linq总结
前言 本文总结学习C#必须知道的基础知识,委托.监视者模式.常用lambda表达式.linq查询,自定义扩展方法,他们之间有什么关系呢?匿名委托是如何演变成lambda表达式,lambda再如何导出l ...
- vim和emacs
vim和emacs 在编程界一直有两大神器的传说.这两大神器一个是emacs,一个是vim.一个是神的编辑器,一个是编辑器之神. 程序员的圈子里面也一直流传着一个段子,说是世界上的程序员分为三种.使用 ...
- python之路(列表,元组)
列表 list:基础数据类型之一,可以索引,切片,步长,切片+步长可以增删改查,可迭代,可嵌套字典,元组,列表 一.索引,切片,步长 list01 = [1,2,3,'eric','west'] 1. ...
- 问题 D: 八皇后
#include <cstdio> #include <vector> #include <algorithm> using namespace std; cons ...
- [CF1303F] Number of Components - 并查集,时间倒流
有一个 \(n \times m\) 矩阵,初态下全是 \(0\). 如果两个相邻元素(四连通)相等,我们就说它们是连通的,且这种关系可以传递. 有 \(q\) 次操作,每次指定一个位置 \((x_i ...
- RocketMQ解决幂等性问题
一.造成重复消费的原因 在于回馈机制.正常情况下,消费者在消费消息时候,消费完毕后,会发送一个ACK确认信息给消息队列(broker),消息队列(broker)就知道该消息被消费了,就会将该消息从消息 ...
- Canvas如何绘制精美的图?
一.Canvas的基本使用 首先在使用Canvas一般先在<body>中添加: <canvas id="></canvas> 然后使用Js进行获取canv ...