Feign 是一个声明式的Web Service 客户端。在Spring Cloud 中使用Feign,可以做到使用HTTP 请求访问远程服务,就像调用本地方法一样。开发者完全感知不到这是在调用远程方法。
Feign 特性:
- 支持可插拔的注解,包括Feign 注解和JAX-RS注解。
- 支持可插拔的HTTP编码器和解码器。
- 支持Hystrix和Fallback。
- 支持Ribbon的负载均衡。
- 支持HTTP请求和响应的压缩。
Feign 依赖包:
<!-- Spring Cloud OpenFeign的Starter的依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
Feign 注解:
FeignClient注解被@Target(ElementType.TYPE)修饰,表示FeignClient注解的作用目标在接口上
@FeignClient(name = "github-client", url = "https://api.github.com", configuration = HelloFeignServiceConfig.class)
public interface GitHubClient {
@RequestMapping(value = "/search/repositories", method = RequestMethod.GET)
String searchRepo(@RequestParam("q") String queryStr);
}
声明接口之后,在代码中通过@Resource注入之后即可使用。
@FeignClient标签的常用属性如下:
- name:指定FeignClient的名称,如果项目使用了Ribbon,name属性会作为微服务的名称,用于服务发现
- url: url一般用于调试,可以手动指定@FeignClient调用的地址
- decode404:当发生http 404错误时,如果该字段位true,会调用decoder进行解码,否则抛出FeignException
- configuration: Feign配置类,可以自定义Feign的Encoder、Decoder、LogLevel、Contract
- fallback: 定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的类必须实现@FeignClient标记的接口
- fallbackFactory: 工厂类,用于生成fallback类示例,通过这个属性我们可以实现每个接口通用的容错逻辑,减少重复的代码
- path: 定义当前FeignClient的统一前缀
Feign的工作原理
没有底层的建立连接、构造请求、解析响应的代码,直接就是用注解定义一个 Feign Client 接口,然后调用那个接口就可以了。
人家 Feign Client 会在底层根据你的注解,跟你指定的服务建立连接、构造请求、发起请求、获取响应、解析响应,等等。这一系列脏活累活,人家 Feign 全给你干了。
那么问题来了,Feign 是如何做到这么神奇的呢?很简单,Feign 的一个关键机制就是使用了动态代理。
- 首先,如果你对某个接口定义了 @FeignClient 注解,Feign 就会针对这个接口创建一个动态代理。
- 接着你要是调用那个接口,本质就是会调用 Feign 创建的动态代理,这是核心中的核心。
- Feign的动态代理会根据你在接口上的 @RequestMapping 等注解,来动态构造出你要请求的服务的地址。
最后针对这个地址,发起请求、解析响应。
Feign Logging 日志记录
每一个被创建的Feign客户端都会有一个feign.Logger 实例。该logger默认的名称为Feign客户端对应的接口的全限定名。可以在配置文件中开启日志,分为两步。
1. 在application.yml 中配置日志输出。
在application.yml 中设置日志输出级别。
logging:
level:
com.rickie.feign.service.HelloFeignService: debug
2. 在Feign 客户端配置类HelloFeignServiceConfig中,配置Feign 日志记录详细信息。
创建带有 @Configuration 注解的类,配置日志bean,代码如下所示。
package com.rickie.feign.config;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class HelloFeignServiceConfig {
/**
*
* Logger.Level 的具体级别如下:
NONE:不记录任何信息
BASIC:仅记录请求方法、URL以及响应状态码和执行时间
HEADERS:除了记录 BASIC级别的信息外,还会记录请求和响应的头信息
FULL:记录所有请求与响应的明细,包括头信息、请求体、元数据
* @return
*/
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
控制台查看对应日志
Feign日志输出效果:
本文暂时没有评论,来添加一个吧(●'◡'●)