Open Feign 简单使用笔记
Open feign 可使远程调用 Http 接口更加遵循面向对象的思想, 使用 Open feign 调用远程API 就像调用本地接口一样
配置
使用版本
Spring boot 2.6.11  + Spring cloud alibaba 2021.0.4.0 
 
依赖包
pom.xml 
1 2 3 4 5
   | <dependency>     <groupId>org.springframework.cloud</groupId>     <artifactId>spring-cloud-starter-openfeign</artifactId>     <version>3.1.3</version> </dependency>
   | 
 
注解
在 Spring boot 启动类上添加 @EnableFeignClients 注解
自定义配置
日志
Open Feign 的日志级别
| 级别 | 
说明 | 
| NONE | 
不记录日志, 性能较佳 | 
| BASIC | 
记录请求方法, URL, 响应状态码, 执行时间 | 
| HEADERS | 
记录 BASIC 日志级别内容以及请求响应的 Header | 
| FULL | 
记录请求, 响应的所有信息 | 
Open Feign 输出日志的前提是在 Spring boot 的配置文件中 logging.level 中 Feign 接口的日志输出级别为 debug 以上
 
配置
全局配置
FeignConfig.java 
1 2 3 4 5 6 7 8 9 10 11 12
   | import feign.Logger; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;
 
  @Configuration public class FeignConfig {     @Bean     Logger.Level feignLoggerLevel(){         return Logger.Level.BASIC;     } }
   | 
 
局部配置
@FeignClient注解中的 configuration 属性指定配置类或在 Spring boot 配置文件中对 feign.client.config.provider.logger-level 属性指定日志级别
feign.client.config.provider.logger-level 中的 provider 为服务名称
 
设置超时时间
全局配置
FeignConfig.java 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   | import feign.Request; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;
  import java.util.concurrent.TimeUnit;
 
  @Configuration public class FeignConfig {     @Bean     Request.Options options(){         return new Request.Options(100, TimeUnit.SECONDS, 1000, TimeUnit.SECONDS, true); 
 
 
 
 
 
      } }
   | 
 
局部配置
@FeignClient注解中的 configuration 属性指定配置类或在 Spring boot 配置文件中设置属性 feign.client.config.provider.connect-timeout  和 feign.client.config.provider.read-timeout 的值
拦截器
Open Feign 的拦截器 需要实现 feign.RequestInterceptor 接口, 拦截器作用于请求之前
1 2 3 4 5 6 7 8 9 10 11 12
   | import feign.RequestInterceptor; import feign.RequestTemplate; import org.springframework.stereotype.Component;
  @Component public class FeignInterceptor implements RequestInterceptor {     @Override     public void apply(RequestTemplate requestTemplate) {         System.out.println(requestTemplate);     } }
 
   | 
 
手动注入可配置 Bean 或在 Spring boot 配置文件中设置属性 feign.client.config.provider.request-interceptors 的值
 
测试使用到的类
实体类
POJO.java 
1 2 3 4 5 6 7 8 9 10 11
   | package com.example.consumer;
  import lombok.Data;
  @Data public class POJO {     String id;     String name;     Integer age; }
 
   | 
 
远程接口
Controller.java 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
   | import com.example.consumer.POJO; import com.fasterxml.jackson.databind.node.POJONode; import org.springframework.boot.autoconfigure.security.SecurityProperties; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController;
  @RestController public class Controller {
      @GetMapping( "/test")     public String get() {         return hello + "1";     }
      @PostMapping     public POJO post(@RequestBody POJO pojo){         return pojo;     } }
 
   | 
 
Open Feign 声明式接口
FeignRemoteCall.java 
1 2 3 4 5 6 7 8 9 10 11 12 13
   | import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody;
  @FeignClient(name = "provider", path = "/") public interface FeignRemoteCall {     @GetMapping( "/test")     public String get();
      @PostMapping     public POJO post(@RequestBody POJO pojo); }
   | 
 
@FeignClient 注解中常用属性
- name (value) 属性 指服务名称
 
- path 属性指 URI 前缀
 
- url 属性 指远程主机地址
 
 
本地调用
FeignController.java 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
   | import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;
  @RestController @RequestMapping("feign") public class FeignController {     private final FeignRemoteCall feignRemoteCall;
      public FeignController(FeignRemoteCall feignRemoteCall) {         this.feignRemoteCall = feignRemoteCall;     }
      @GetMapping("/get")     public String get(){         return feignRemoteCall.get();     }
      @GetMapping("/post")     public POJO post(){         POJO pojo = new POJO();         pojo.setName("username");         pojo.setId("id001");         pojo.setAge(21);         return feignRemoteCall.post(pojo);     } }
   | 
 
注解
Spring MVC 注解
@FeignClient 类中默认可以使用 @RequestMapping, @GetMapping, @PathVariable 等 Spring MVC 中的注解, 注解意义与 Spring MVC 中相同
Open Feign 注解
配置
全局配置
FeignController.java 
1 2 3 4 5 6 7 8 9 10 11 12
   | import feign.Contract; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;
 
  @Configuration public class FeignConfig {    @Bean     Contract contract(){        return new Contract.Default();    } }
   | 
 
局部配置
@FeignClient注解中的 configuration 属性指定配置类或在 Spring boot 配置文件中设置属性 feign.client.config.provider.contract 值为 feign.Contract.Default
映射关系
@RequestMapping -> @RequestLine
@PathVariable -> @Param
…
JAX-RS 注解