Spring Cloud 远程调用核心组件介绍

lili_lu 发表于 2021/06/04 18:27:14 2021/06/04
【摘要】 核心组件与概念读者在阅读Feign源码时,可以沿着两条路线进行,一是FeignServiceClient这样的被@FeignClient修饰的接口类如何被创建出来,也就是其Bean对象是如何被构建的,二是调用FeignServiceClient对象的响应方法时,Feign是如何发送网络请求的。而Feign相关的类也可以以此来进行分类,一部分是用来初始化相应的Bean示例的,一部分是用来在调...

核心组件与概念

读者在阅读Feign源码时,可以沿着两条路线进行,一是FeignServiceClient这样的被@FeignClient修饰的接口类如何被创建出来,也就是其Bean对象是如何被构建的,二是调用FeignServiceClient对象的响应方法时,Feign是如何发送网络请求的。而Feign相关的类也可以以此来进行分类,一部分是用来初始化相应的Bean示例的,一部分是用来在调用方法时发送网络请求的。
image.png

Feign关键类的类图

上图是Feign相关的关键类图,其中比较重要的类为FeignClientFactoryBean,FeignContext,SynchronousMethodHandler。其中FeignClientFactoryBean可以创建@FeignClient修饰的接口类Bean示例;FeignContext作为配置的上下文环境,保存着相关组件的不同实例,这些示例都是按照不同的FeignConfiguration所构造出来的;SynchronousMethodHandlerMethodHandler的子类,可以在相应方法被调用时发送网络请求,然后再将请求响应转化为函数返回值进行输出。
image.png

源码流程图

图是后续源码讲解的流程图,Feign会首先进行相关BeanDefinition的动态注册,然后当spring容器注入相关实例时会进行实例的初始化,最后当相关实例的函数被调用时会进行发送网络请求。

动态注册BeanDefinition

Feign可以通过多种方式进行自定义配置,配置的变化会导致接口类初始化时使用不同的实现类,从而控制Feign的相关行为,比如说网络请求的编解码,压缩和日志处理。可以说,了解Feign配置和实例初始化的流程和原理对于我们学习和使用Feign有着至关重要的作用,而且Spring Cloud的所有项目的配置和实例初始化过程原理基本相同,了解了Feign的原理,就可以触类旁通,一通百通了。

在快速入门一节已经介绍了@EnableFeignClients的基本作用,它就像是Feign的总开关,一切Feign的相关的操作都是从它开始的。@EnableFeignClients有三个作用,一是是引入FeignClientsRegistrar;二是指定扫描FeignClient的package信息,就是指定你所有FeignClient所在的包名;三是指定FeignClient的自定义配置类。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
//ImportBeanDefinitionRegistrar的子类,用于处理@FeignClient注解。
@Import(FeignClientsRegistrar.class)
public @interface EnableFeignClients {

	/**
	 * 下面三个函数都是为了指定需要扫描的basepackage。
	 **/
	String[] value() default {};
	String[] basePackages() default {};

	Class<?>[] basePackageClasses() default {};


	/**
	 * 指定自定义feign client的自定义configuration,可以配置Decoder,Encoder和Contract,FeignClientsConfiguration是默认的配置类
	 */
	Class<?>[] defaultConfiguration() default {};

	/**
	 * 指定被@FeignClient修饰的类,如果不为空,那么路径自动检测机制会被关闭
	 * List of classes annotated with @FeignClient. If not empty, disables classpath scanning.
	 * @return
	 */
	Class<?>[] clients() default {};
}

FeignClientsRegistrarImportBeanDefinitionRegistrar的子类,Spring用ImportBeanDefinitionRegistrar来动态注册BeanDefinition。Feign通过FeignClientsRegistrar来处理@FeignClient修饰的FeignClient类,将这些接口的BeanDefinition注册到Spring容器中。这样就可以使用@Autowired来自动装载这些FeignClient的Bean实例,从而可以调用这些实例的方法发送网络请求。

class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar,
		ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {
	//....代码有删减
	@Override
	public void registerBeanDefinitions(AnnotationMetadata metadata,
			BeanDefinitionRegistry registry) {
    //从EnableFeignClients的属性值来构建Feign的自定义Configuration进行注册
		registerDefaultConfiguration(metadata, registry);
    //扫描package,注册被@FeignClient修饰的接口类的bean信息
		registerFeignClients(metadata, registry);
	}
	//代码有删减
}

FeignClientsRegistrarregisterBeanDefinitions函数主要做了两个事情,一是注册@EnableFeignClients提供的自定义配置类中的相关Bean信息,二是根据@EnableFeignClients提供的包信息扫描被@FeignClient修饰的FeignCleint接口类,然后进行注册。

下面的文章将会关注其他核心类的实现。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区),文章链接,文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:cloudbbs@huaweicloud.com进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。