使用Feign实现声明式Rest调用

一,前言
使用RestTemplate实现Rest API调用时,我们是使用拼接字符串的方式拼接URL的,URL中如果有参数而且参数比较多,这就变得难以维护。

二,Feign简介
Feign是Netflix开发的声明式、模板化的Http客户端,其灵感来自Retrofit、JAXRS-2.0以及WebSocket。Feign可以更便捷、优雅的调用Http API
在Spring Cloud中使用Feign非常简单,创建一个接口,并在接口上添加注解就完成了。
Feign支持多种注解,Feign自带的或JAX-RS注解等。
Spring Cloud对Feign进行了增强,使Feign支持了SpringMVC注解,并整合了Ribbon和Eureka,从而让Feign的使用更加方便。

三,为消费者整合Feign
1,添加Feign依赖

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>

2,创建Feign接口,并添加@FeignClient注解
/**

  • Feign客户端接口

  • @author yebin

  • @date 2020/12/8 10:44

  • @since 1.0.1
    */
    @FeignClient(name = "movie-provider")
    public interface UserFeignClient {

    @RequestMapping(value = "/{id}",method = RequestMethod.GET)
    public User findById(@PathVariable("id") Long id);
    }

3,修改Controller及启动类
@RestController
@Slf4j
public class UserController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@Autowired //注入负载均衡客户端
private LoadBalancerClient loadBalancerClient;
@Autowired
private UserFeignClient userFeignClient;

//feign方式调用
@GetMapping("/user/feign/{id}")
public User findByIdFeign(@PathVariable Long id) {
    return this.userFeignClient.findById(id);
}

//restTemplate方式调用
@GetMapping("/user/{id}")
public User findById(@PathVariable Long id) {
    return this.restTemplate.getForObject("http://movie-provider:8091/" + id, User.class);
}

@GetMapping("/user/list")
public List<User> findAll() {
    return restTemplate.getForObject("http://movie-provider:8091/list", List.class);
}

/**
 * 获取提供者元数据信息
 * @return
 */
@GetMapping("/provider/instance")
public List<ServiceInstance> getServiceInstance(){
    return  discoveryClient.getInstances("movie-provider");
}

/**
 * 打印当前选择的是哪个节点
 * 注意:
 * 不能将restTemplate.getForObject()与loadBalancerClient.choose()写在一个方法中,两者会引起冲突,因为代码中restTemplate实际上
 * 是一个Ribbon客户端,本身已经包含了choose行为。
 */
@GetMapping("/print-instance")
public void printInstance(){
    ServiceInstance serviceInstance = loadBalancerClient.choose("movie-provider");
    log.info("serviceId--->{},host--->{},port--->{}",serviceInstance.getServiceId(),serviceInstance.getHost(),serviceInstance.getPort());
}

}

/**

  • 1,@EnableDiscoveryClient 声明这是一个Eureka Client,此处可用@EnableEurekaClient代替。

  • 2,spring cloud 中服务发现组件有多种,如:Zookeeper,Consul等,@EnableDiscoveryClient为各种组件提供了支持。

  • 3,@EnableDiscoveryClient是spring-cloud-commons项目的注解,是一个高度的抽象。

  • 4,@EnableEurekaClient表明是Eureka 的Client,该注解是是spring-cloud-netflix项目的,只能与Eureka一起工作。
    */
    @EnableDiscoveryClient
    //@EnableEurekaClient
    @SpringBootApplication
    @EnableFeignClients //启用Feign客户端
    public class MovieConsumerFeignApplication {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
    return new RestTemplate();
    }

    public static void main(String[] args) {
    SpringApplication.run(MovieConsumerFeignApplication.class, args);
    }

}

4,自定义Feign配置


image.png

image.png

/**

  • Feign自定义配置类

  • Feign配置类不应放在与启动类同一个包下,否则该类中的配置信息就会被所有@FeignClient共享,或者显式指定

  • @ComponetScan不扫描@Configuration所在的包

  • @author yebin

  • @date 2020/12/8 11:06

  • @since 1.0.1
    */
    @Configuration
    public class FeignConfiguration {

    //将契约改为feign原生的契约,这样可以使用feign自带的注解了。
    @Bean
    public Contract feignContract(){
    return new feign.Contract.Default();
    }
    }

5,Feign对继承的支持
Feign支持继承,可将一些公共操作抽到父接口中,以简化Feign的操作。


image.png

6,Feign对压缩的支持
一些场景下需要对请求或响应进行压缩,此时可以使用以下属性来启用Feign的压缩功能。
feign.compression.request.enable=true
feign.compression.response.enable=true
对于请求的压缩,Feign还可以更为详细的设置:
feign.compression.request.enable=true

支持的媒体类型

feign.compression.request.mime-types=text/xml,application/xml,application/json

请求的最小阈值,默认是2048

feign.compression.request.min-request-size=2048

7,Feign的日志
Feign对日志处理非常灵活,可为每个Feign客户端指定日志记录策略,每个Feign客户端都会记录一个logger。默认情况下,logger的名称是Feign接口的完事类名,需要注意的是Feign的日志只会对DEBUG级别日志做出响应。


image.png
7.1 Feign的配置类

/**

  • Feign自定义配置类
  • Feign配置类不应放在与启动类同一个包下,否则该类中的配置信息就会被所有@FeignClient共享,或者显式指定
  • @ComponetScan不扫描@Configuration所在的包
  • @author yebin
  • @date 2020/12/8 11:06
  • @since 1.0.1
    */
    @Configuration
    public class FeignConfiguration {
    //Feign日志
    @Bean
    Logger.Level feignLoggerLevel(){
    return Logger.Level.FULL;
    }
    }

8,使用Feign构造多请求的参数
Spring Cloud为Feign添加了Spring MVC注解的支持,可以使用参照Spring MVC注解的方式来构造多请求参数
GET请求:
8.1
@Configuration
public class FeignConfiguration {
@GetMapping("/get")
public User get(@RequestParam("id") Long id,@RequestParam("username") String username){
...
}
}
POST请求:
@RestController
@Slf4j
public class UserController {
@PostMapping("/post")
public User post(@RequestBody User user){
return null;
}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,198评论 6 514
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,334评论 3 398
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,643评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,495评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,502评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,156评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,743评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,659评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,200评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,282评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,424评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,107评论 5 349
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,789评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,264评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,390评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,798评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,435评论 2 359

推荐阅读更多精彩内容