简介

Feign是一个声明式的Web Service客户端,它简化了Web服务客户端的编写操作,相对于Ribbon+RestTemplate的方式,开发者只需通过简单的接口和注解来调用HTTP API。它支持Spring MVC注解和JAX-RS注解,还支持可插拔式的编码器和解码器。整合了Eureka,Ribbon和Hystrix,具有可插拔、基于注解、负载均衡、服务熔断等一系列便捷功能。

项目介绍

  1. sc-parent,父模块(请参照SpringCloud学习笔记(1):Eureka注册中心)
  2. sc-eureka,注册中心(请参照SpringCloud学习笔记(1):Eureka注册中心)
  3. sc-provider,提供者(请参照SpringCloud学习笔记(1):Eureka注册中心)
  4. sc-consumer-feign,基于Feign声明式调用的消费者

基于Feign声明式调用的消费者

1.在父模块下创建子模块项目sc-consumer-feign,pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.cf</groupId>
<artifactId>sc-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>sc-consumer-feign</artifactId> <dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
</project>

2.创建启动类feign.FeignApplication:

package feign;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication
@EnableFeignClients
public class FeignApplication {
public static void main(String[] args) {
SpringApplication.run(FeignApplication.class, args);
}
}

3.创建Feign声明式接口:feign.inter.BookService

package feign.inter;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping; @FeignClient("sc-provider")
public interface BookService { @GetMapping("/book/list")
public String getBookList();
}

4.创建调用提供者服务的Controller:

package feign.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import feign.inter.BookService; @RequestMapping("/feign")
@RestController
public class FeignController {
@Autowired
private BookService bookService; @GetMapping("/getBookList")
public String getBookList(){
return bookService.getBookList();
}
}

5.创建application.yml:

server:
port: 8084 spring:
application:
name: sc-consumer-feign eureka:
client:
registerWithEureka: false
serviceUrl:
defaultZone: http://localhost:8080/eureka/

6.依次启动注册中心sc-eureka、提供者sc-provider、消费者sc-consumer-feign,并访问http://localhost:8084/feign/getBookList:

Feign基于Ribbon实现,也具有Ribbon负载均衡的特性,可以将调用的提供者服务换成sc-provider-random(请参照SpringCloud学习笔记(2):使用Ribbon负载均衡)来测试。

带参数的请求

上面例子没有涉及到参数的传递,接下来测试下如何使用Feign构造带参数的请求,首先对提供者和消费者做如下更改:

//提供者Controller添加了两个参数,并打印到控制台。
@RequestMapping("/book")
@RestController
public class BookController {
@GetMapping("/list")
public String getBookList(String param1, Integer param2){
System.out.println(param1 + ":" + param2);
return "[\"Java入门到放弃\",\"C++入门到放弃\",\"Python入门到放弃\",\"C入门到放弃\"]";
}
} //消费者Feign接口和Controller添加参数
@FeignClient("sc-provider")
public interface BookService {
@GetMapping("/book/list")
public String getBookList(String param1, Integer param2);
} @RequestMapping("/feign")
@RestController
public class FeignController {
@Autowired
private BookService bookService; @GetMapping("/getBookList")
public String getBookList(){
return bookService.getBookList("Java", 520);
}
}

依次启动注册中心sc-eureka、提供者sc-provider、消费者sc-consumer-feign,启动消费者sc-consumer-feign时会启动失败:

java.lang.IllegalStateException: Method has too many Body parameters: public abstract java.lang.String feign.inter.BookService.getBookList(java.lang.String,java.lang.Integer)

解决方法1

更改Feign接口,为参数添加@RequestParam注解:

@FeignClient("sc-provider")
public interface BookService {
@GetMapping("/book/list")
public String getBookList(@RequestParam("param1") String param1, @RequestParam("param2") Integer param2);
}

解决方法2

将参数封装到Map里,更改消费者Feign接口和Controller:

@FeignClient("sc-provider")
public interface BookService {
@GetMapping("/book/list")
public String getBookList(@RequestParam Map<String, Object> paramMap);
} @RequestMapping("/feign")
@RestController
public class FeignController {
@Autowired
private BookService bookService; @GetMapping("/getBookList")
public String getBookList(){
Map<String,Object> paramMap = new HashMap<String, Object>();
paramMap.put("param1", "Java");
paramMap.put("param2", 520);
return bookService.getBookList(paramMap);
}
}

在参数较多的情况下,该方式可以简化Feign接口的编写。

自定义类型的参数

OpenFeign的@QueryMap注解支持将自定义类型用于GET参数映射,由于@QueryMap和Spring不兼容,Spring Cloud OpenFeign提供了一个等价的@SpringQueryMap注解,可以用于自定义类型和Map类型的参数映射。下面将使用自定义类型Params作为参数,使用@SpringQueryMap注解来处理自定义类型的参数映射。

1.分别在提供者和消费者中创建类Params(可以建一个公共模块,然后在提供者和消费者中添加依赖):

public class Params {
private String param1; private Integer param2; public String getParam1() {
return param1;
} public void setParam1(String param1) {
this.param1 = param1;
} public Integer getParam2() {
return param2;
} public void setParam2(Integer param2) {
this.param2 = param2;
} @Override
public String toString() {
return "Params [param1=" + param1 + ", param2=" + param2 + "]";
} public Params(String param1, Integer param2) {
this.param1 = param1;
this.param2 = param2;
} public Params() {}
}

2.更改提供者和消费者相关类

//提供者
@RequestMapping("/book")
@RestController
public class BookController {
@GetMapping("/list")
public String getBookList(Params params){
System.out.println(params.toString());
return "[\"Java入门到放弃\",\"C++入门到放弃\",\"Python入门到放弃\",\"C入门到放弃\"]";
}
} //消费者
@FeignClient("sc-provider")
public interface BookService {
@GetMapping("/book/list")
public String getBookList(@SpringQueryMap Params params);
} @RequestMapping("/feign")
@RestController
public class FeignController {
@Autowired
private BookService bookService; @GetMapping("/getBookList")
public String getBookList(){
Params params = new Params("Java", 520);
return bookService.getBookList(params);
}
}

3.依次启动注册中心sc-eureka、提供者sc-provider、消费者sc-consumer-feign,并访问http://localhost:8084/feign/getBookList,提供者控制台输出:

Params [param1=Java, param2=520]

SpringCloud学习笔记(3):使用Feign实现声明式服务调用的更多相关文章

  1. SpringCloud系列-利用Feign实现声明式服务调用

    上一篇文章<手把手带你利用Ribbon实现客户端的负载均衡>介绍了消费者通过Ribbon调用服务实现负载均衡的过程,里面所需要的参数需要在请求的URL中进行拼接,但是参数太多会导致拼接字符 ...

  2. SpringCloud 源码系列(6)—— 声明式服务调用 Feign

    SpringCloud 源码系列(1)-- 注册中心 Eureka(上) SpringCloud 源码系列(2)-- 注册中心 Eureka(中) SpringCloud 源码系列(3)-- 注册中心 ...

  3. spring cloud 入门系列五:使用Feign 实现声明式服务调用

    一.Spring Cloud Feign概念引入通过前面的随笔,我们了解如何通过Spring Cloud ribbon进行负责均衡,如何通过Spring Cloud Hystrix进行服务断路保护,两 ...

  4. SpringCloud系列十:使用Feign实现声明式REST调用

    1. 回顾 前文的示例中是使用RestTemplate实现REST API调用的,代码大致如下: @GetMapping("/user/{id}") public User fin ...

  5. SpringCloud(四):使用Feign实现声明式服务调用

    一.Feign介绍Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单.使用Feign,只需要创建一个接口并注解.它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解 ...

  6. springCould:使用Feign 实现声明式服务调用

    一.Spring Cloud Feign概念引入通过前面的随笔,我们了解如何通过Spring Cloud ribbon进行负责均衡,如何通过Spring Cloud Hystrix进行服务断路保护,两 ...

  7. Spring Cloud Feign声明式服务调用(转载)+遇到的问题

    转载:原文 总结: 1.pom添加依赖 2.application中填写正确的eureka配置 3.启动项中增加注解 @EnableFeignClients 4.填写正确的调用接口 通过原文使用Fei ...

  8. 声明式服务调用:Spring Cloud Feign

    最近在学习Spring Cloud的知识,现将声明式服务调用:Spring Cloud Feign 的相关知识笔记整理如下.[采用 oneNote格式排版]

  9. 6.使用Feign实现声明式REST调用

                        使用Feign实现声明式REST调用 6.1. Feign简介 Feign是一个声明式的REST客户端,它的目的就是让REST调用更加简单. Feign提供了H ...

随机推荐

  1. Ubuntu 16.04 硬盘安装

    自己的宏碁4741G 笔记本,已经用了6年了,最近感觉越来越慢,晚上突然想起装个Linux 玩玩,说干就干,选择了用户比较多的Ubuntu,网上下载16.04的版本,结合网上搜索到的安装教程,看似简单 ...

  2. 【PYTHON】语法基础 | 开始使用Python

    Python的热度不言而喻,机器学习.数据分析的首选语言都是Python,想要学习Python的小伙伴也很多,我之前也没有认真用过Python,所以也想体验一下它的魅力,索性花了两天集中看了一下它的基 ...

  3. pycharm的安装配置及思维导图

    1.1 计算机基础知识 主板:人的骨架,用于扩展设备的 cpu:人的大脑,用于计算和逻辑处理的 硬盘:存储数据(永久存储) 电源:人的心脏 内存:存储数据(临时存储) 断电即消失 操作系统 xp wi ...

  4. 零拷贝Zero copy-linux and java

    背景-几种拷贝方式 方式1:Copying in Two Sample System Calls read(file, tmp_buf, len); write(socket, tmp_buf, le ...

  5. spring-boot-plus详细配置(五)

    spring-boot-plus详细配置 公共配置 application.yml

  6. hbase集群region数量和大小的影响

    1.Region数量的影响 通常较少的region数量可使群集运行的更加平稳,官方指出每个RegionServer大约100个regions的时候效果最好,理由如下: 1)Hbase的一个特性MSLA ...

  7. 积性函数&线性筛&欧拉函数&莫比乌斯函数&因数个数&约数个数和

    只会搬运YL巨巨的博客 积性函数 定义 积性函数:对于任意互质的整数a和b有性质f(ab)=f(a)f(b)的数论函数. 完全积性函数:对于任意整数a和b有性质f(ab)=f(a)f(b)的数论函数 ...

  8. IT人不仅要提升挣钱能力,更要拓展挣钱途径

    前几天我上班路上,和小区门口开车的师傅闲聊,发现他们虽然学历不高,但挣钱的途径不少,比如固定接送多位客户,然后能通过朋友圈拓展新客户,而且通过客户口口相传,也能不断拉到生意,算下来每月也能挣1万5出头 ...

  9. java.lang.TypeNotPresentException: Type javax.xml.bind.JAXBContext not present解决方案

    因为JAXB-API是java ee的一部分,在jdk9中没有在默认的类路径中: java ee api在jdk中还是存在的,默认没有加载而已,jdk9中引入了模块的概念,可以使用 模块命令--add ...

  10. python 18 re模块

    目录 re 模块 1. 正则表达式 2. 匹配模式 3. 常用方法 re 模块 1. 正则表达式 \w 匹配字母(包含中文)或数字或下划线 \W 匹配非字母(包含中文)或数字或下划线 \s 匹配任意的 ...