文章目录
1、什么是 Feign ?
Feign是 Netflix 公司开发的声明式、轻量级Restful的HTTP服务客户端,内置了Ribbon,用于客户端负载均衡。
OpenFeign 是 Spring Cloud 在 Feign 的基础上支持了SpringMVC的注解,如@RequesMapping等等。
在之前我们学习了注册中心,将服务注册到注册中心,然后通过 RestTemplate
类去调用服务,但是在调用服务时,我们需要拼接服务的地址和参数等信息。为了简化这个步骤,我们就需要使用 Feign 。
2、使用 OpenFeign
想要在项目中使用 OpenFeign ,我们必须完成如下几个步骤:
-
在项目中导入所需依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
-
创建一个Feign接口:此接口是在Feign中调用微服务的核心接口,需要使用
@FeignClient
注解,一般一个接口对应一个服务。@FeignClient(name="需要调用的服务在注册中心的服务名称") public interface ProductFeginClient { //具体调用的请求路径 @RequestMapping(value = "/product/{id}",method = RequestMethod.GET) public Product findById(@PathVariable("id") Long id); }
-
修改启动类:在启动类上添加
@EnableFeignClients
注解;@SpringBootApplication @EnableFeignClients public class EurekaClientApplication{ //省略.... //删除 关于对 restTemplate 的注入,因为不再直接使用 restTemplate 对象 }
-
修改服务调用
@RestController @RequestMapping("/order") public class OrderController { //不再直接使用 restTemplate 对象进行调用 //@Autowired //private RestTemplate restTemplate; @Autowired private ProductFeginClient productFeginClient; @GetMapping("/buy/{id}") public Product order(@PathVariable Long id) { return productFeginClient.findById(id); } }
在使用了 OpenFeign 之后的访问流程是:
- 浏览器访问
localhost/order/buy/1
- 调用 OrderController 类中的 order 方法
- order 方法再调用 ProductFeginClient 接口的 findById 类
- findById 类在去通过 OpenFeign 调用其他的服务
3、Feign 的相关配置
在使用 Feign 时,可以添加一些配置对 Feign 进行配置。
feign:
compression:
request:
enabled: true # 开启请求压缩
mime-types: text/html,application/xml,application/json # 设置压缩的数据类型
min-request-size: 2048 # 设置触发压缩的大小下限
response:
enabled: true # 开启响应压缩
client:
config:
Name: #具体的feign接口名称
connectTimeout: 5000
readTimeout: 5000
# 配置Feign的日志级别,相当于代码配置方式中的Logger
loggerLevel: full
# Feign的错误解码器,相当于代码配置方式中的
ErrorDecoder errorDecoder: com.example.SimpleErrorDecoder
# 配置重试,相当于代码配置方式中的
Retryer retryer: com.example.SimpleRetryer
# 配置拦截器,相当于代码配置方式中的
RequestInterceptor requestInterceptors:
- com.example.FooRequestInterceptor
- com.example.BarRequestInterceptor
decode404: false
logging:
level:
feign接口的全限定名: debug
-
Feign 支持对请求和响应进行压缩,以减少通信过程中的性能损耗。通过配置项中的
compression
可以开启压缩功能。feign: compression: request: enabled: true # 开启请求压缩 mime-types: text/html,application/xml,application/json # 设置压缩的数据类型 min-request-size: 2048 # 设置触发压缩的大小下限 response: enabled: true # 开启响应压缩
-
在开发阶段往往希望看到 Feign 请求过程的日志记录,在默认情况下 Feign 的日志是没有开启的。所以想要开启日志,通过下列配置对具体的Feign 接口进行设置。
feign: client: config: Name: #具体的feign接口名称 loggerLevel: full logging: level: feign接口的全限定名: debug
logging: level: feign接口的全限定名: debug
Feign日志只会对日志级别为debug的做出响应loggerLevel
有四个属性值,NONE(不记录任何日志(默认值))
、BASIC(仅记录请求方法、URL、响应状态代码以及执行时间)
、HEADERS(在BASIC基础上,记录请求和响应的header)
、FULL(记录请求和响应的header、body和元数据)
4、@EnableFeignClients 和 @FeignClient
在使用 Feign 的过程中,我们使用了两个注解@EnableFeignClients
和 @FeignClient
,下面我们对着两个注解进行分析。
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({FeignClientsRegistrar.class})
public @interface EnableFeignClients {
}
从@EnableFeignClients
注解的声明中可以看出,注解中引入了 FeignClientsRegistrar 类:
class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, EnvironmentAware {
//......
}
这个类实现了 ImportBeanDefinitionRegistrar 接口,所以在类中有一个 registerBeanDefinitions() 方法:
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
this.registerDefaultConfiguration(metadata, registry);
this.registerFeignClients(metadata, registry);
}
这个 registerBeanDefinitions() 方法主要用于解析和注册BeanDefinition,注册的对象类型有两种:
- 注册配置的配置信息
- 注册那些添加了
@FeignClient
注解的类或接口
public void registerFeignClients(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
//......
}
上述这个方法就是 registerBeanDefinitions() 方法中调用的那个方法。这个方法主要用于扫描整个工程下面的被 @FeignClient
注解声明的类或接口,然后对这些类进行初始化配置。最后会调用 registerBeanDefinition() 方法完成注册。
private void registerFeignClient(BeanDefinitionRegistry registry, AnnotationMetadata annotationMetadata, Map<String, Object> attributes) {
}