Spring Cloud Feign简介

Spring Cloud官方原文:

A central concept in Spring Cloud’s Feign support is that of the named client. Each feign client is part of an ensemble of components that work together to contact a remote server on demand, and the ensemble has a name that you give it as an application developer using the@FeignClient annotation. Spring Cloud creates a new ensemble as anApplicationContext on demand for each named client usingFeignClientsConfiguration. This contains (amongst other things) anfeign.Decoder, afeign.Encoder, and afeign.Contract.

Spring Cloud lets you take full control of the feign client by declaring additional configuration (on top of the FeignClientsConfiguration) using @FeignClient.

翻译:
Spring Cloud的Feign支持中的一个中心概念是命名的客户端。 每个feign客户端都是组件的一部分,这些组件是按需联系远程服务器的组件的一部分,并且集合有一个名称,您可以使用@FeignClient注释将其作为应用程序开发人员提供。 Spring Cloud使用FeignClientsConfiguration创建一个新的集合,作为每个指定客户端的ApplicationContext。 这包含(其中包括)feign.Decoderfeign.Encoderfeign.Contract

通过使用@FeignClient声明额外的配置(在FeignClientsConfiguration之上),Spring Cloud可让您完全控制Feign客户端。

覆盖Feign的默认配置

定义Feign客户端接口

1
2
3
4
5
@FeignClient(name = "microservice-springcloud-user",configuration = MyConfiguration.class)
public interface UserFeignClient {
    @RequestLine("GET /sample/{userId}")
    User findUserById(@Param("userId") Long userId);
}

自定义FeignClientsConfiguration

1
2
3
4
5
6
7
@Configuration
public class MyConfiguration {
    @Bean
    public Contract feignContract() {
        return new feign.Contract.Default();
    }
}

使用的Controller

1
2
3
4
5
6
7
8
9
@RestController
public class MovieController {
    @Autowired
    private UserFeignClient userFeignClient;
    @GetMapping("/findUser/{userId}")
    public User findUserById(@PathVariable Long userId) {
        return this.userFeignClient.findUserById(userId);
    }
}

注意:FeignClientsConfiguration类不在Spring Boot启动类的扫描路径下,否则会覆盖该项目所有的Feign接口的默认配置。

测试

  • 1.启动Eureka Server;
  • 2.启动microservice-springcloud-user服务;
  • 3.启动microservice-springcloud-movie-feign-customization(本例中的测试项目);
    浏览器输入http://10.41.12.63:7901/findUser/1

    请求成功。

1.@FeignClient注解的serviceId参数不建议被使用。
2.以前使用@FeignClient注解的时候使用了url参数,name参数不是必须的;但现在name必须,只是作为一个标识。
* 3.Feign默认使用的spring MVC的注解,参考《springcloud系列10——Feign的简介及基础使用》。如果覆盖了Feign的默认配置,则需要使用Feign的注解。

@FeignClient使用name和url的示例

这里使用的Feign的默认配置。

1
2
3
4
5
@FeignClient(name = "test", url = "http://localhost:8761")
public interface FeignClient2 {
    @RequestMapping(value = "/eureka/apps/{serviceName}", method = RequestMethod.GET)
    String findServiceInfo(@PathVariable("serviceName") String serviceName);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@RestController
public class MovieController {
    @Autowired
    private UserFeignClient userFeignClient;
    @Autowired
    private FeignClient2 feignClient2;
    @GetMapping("/findUser/{userId}")
    public User findUserById(@PathVariable Long userId) {
        return this.userFeignClient.findUserById(userId);
    }
    @GetMapping("/service/{serviceName}")
    public String findServiceInfoFromEureka(@PathVariable String serviceName) {
        return this.feignClient2.findServiceInfo(serviceName);
    }
}

注意目录结构:

FeignConfiguration类如果加了@Configuration注解,则不能被@ComponetScan扫描到,可以不加这个注解。
Spring Cloud官方文档有说:

参考:Spring Cloud官方文档——spring-cloud-feign-overriding-defaults

Feign日志配置

为每个创建的Feign客户端创建一个记录器。 默认情况下,记录器的名称是用于创建Feign客户端的接口的完整类名称。 Feign日志记录只响应DEBUG级别。

配置日志级别

在application.yml中增加FeignClient的日志级别(注意:每个FeignClient是单独配置的)

1
2
3
logging:
  level:
    com.tommy.springcloud.config.feign.UserFeignClient: DEBUG

设置记录哪些日志

1
2
3
4
5
6
7
8
9
10
public class MyConfiguration {
    @Bean
    public Contract feignContract() {
        return new feign.Contract.Default();
    }
    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
}

这里配置日志记录所有请求和响应信息,包括请求头、请求体、元数据

测试

日志记录的选择

您可以为每个客户端配置的Logger.Level对象告诉Feign需要记录多少。 选择是:

  • NONE:不记录(默认)。
  • BASIC:只记录请求方法和URL以及响应状态码和执行时间。
  • HEADERS:记录基本信息以及请求和响应标题。
  • FULL:记录请求和响应的标题,正文和元数据。

参考:Spring Cloud官方文档——Feign logging