最新实战案例锦集:《Spring Boot3实战案例合集》持续更新,每天至少更新一篇文章,订阅后将赠送文章最后展示的所有MD文档(学习笔记)。
环境:SpringBoot3.2.5
请先确保已经阅读了下面2篇文章:
推荐学习!拆解Spring Cloud 4大核心组件,彻底搞懂工作原理(服务注册与发现)
推荐学习!拆解Spring Cloud 4大核心组件,彻底搞懂工作原理(负载均衡)
1. 简介
Feign 是一个声明式的 Web 服务客户端。它让编写 Web 服务客户端变得更加容易。要使用 Feign,您需要创建一个接口并对其进行注解。Feign 支持可插拔的注解,包括 Feign 自身的注解和 JAX-RS 注解。Feign 还支持可插拔的编码器和解码器。Spring Cloud 增加了对 Spring MVC 注解的支持,并且可以使用 Spring Web 默认使用的相同的 HttpMessageConverters。Spring Cloud 集成了 Eureka、Spring Cloud 断路器以及 Spring Cloud 负载均衡器,以便在使用 Feign 时提供负载均衡的 HTTP 客户端。
之前有几篇文章已经介绍过有关OpenFeign的详细使用,如果你还不是非常熟悉,那么推荐你先看这几篇文章:
本篇文章我们将详细的介绍OpenFeign的底层工作原理。
2. 工作原理
要使用OpenFeign,我们只需要下面两步即可。
第一步:
使用@EnableFeignClients注解开启OpenFeign支持,如下示例:
public class Application {}
第二步:
定义远程调用的接口,然后使用@FeignClient声明,如下实例:
public interface PackClient {
List<Info> get() ;
}
到此,我们就可以在其它bean的内部注入PackClient对象,调用方法即可。非常的简单,接下来我们将详细的介绍上面两步到底做了什么,一个接口+一个注解(@FeignClient)就可以调用方法了(常规认知,你的有接口实现啊);不过如果你懂MyBatis中的Mapper接口怎么一回事,那也就大概能猜到这里一回事了。
2.1 @EnableFeignClients注解做了什么?
源码如下:
public EnableFeignClients {
/**扫描的包*/
String[] value() default {};
/**要扫描的包*/
String[] basePackages() default {};
/**用于指定要扫描的组件包的安全类型替代方案。每个指定类的包都将被扫描。*/
Class<?>[] basePackageClasses() default {};
/**
*为所有Feign客户端提供的自定义@Configuration。可以包含用于覆盖客户端组成部分的 @Bean 定义,
*例如 feign.codec.Decoder、feign.codec.Encoder、feign.Contract
*/
Class<?>[] defaultConfiguration() default {};
/** 标注有@FeignClient注解的类列表。如果此列表非空,则禁用类路径扫描*/
Class<?>[] clients() default {};
}
注意:OpenFeign与上一篇LoadBalancer一样,它会为每一个客户端创建单独的一个Spring容器(AnnotationConfigApplicationContext)对象来管理默认或者是自定义的配置(如上defaultConfiguration属性如果配置了,那么它会为所有的客户端@FeignClient容器都注册该默认配置)。
通过上面的源码,你也清楚了该注解核心是@Import注解导入的类,接下来我们来看改FeignClientsRegistrar到底做了什么。
2.2 FeignClientsRegistrar注册类
根据该类名大概能猜到,用来注册相关bean的。
class FeignClientsRegistrar implements
ImportBeanDefinitionRegistrar,
ResourceLoaderAware,
EnvironmentAware {}
该类实现了 ImportBeanDefinitionRegistrar 该类的作用就是用来注册BeanDefinition。该接口只要两个默认方法如下,通常只需要实现下面这一个方法:
default void registerBeanDefinitions(
AnnotationMetadata metadata,
BeanDefinitionRegistry registry) {
}
FeignClientsRegistrar实现的方法如下:
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
// 1.注册默认的配置
registerDefaultConfiguration(metadata, registry);
// 2.注册@FeignClient注解的客户端接口
registerFeignClients(metadata, registry);
}