spring-cloud-openfeign简述


发布于 2021-05-26 / 34 阅读 / 0 评论 /
feign是微服务之间接口的调用方式

1.spring-cloud-openfeign概述

在官方文档中,feign的定义是:Feign是一种声明式、模板化的HTTP客户端。

Spring Cloud OpenFeign作为Spring Cloud的子项目,为微服务架构下服务之间的调用提供了解决方案。

Feign的核心特性如下图所示:

2.Feign接口调用过程

调用过程如下图所示:

3.feign-client配置

配置类为org.springframework.cloud.openfeign.FeignClientProperties,在spring-cloud-openfeign-core包中定义。

feign:
    client:
        config:
            feignName:
                connectTimeout: 5000
                readTimeout: 5000
                loggerLevel: full
                errorDecoder: com.example.SimpleErrorDecoder
                retryer: com.example.SimpleRetryer
                defaultQueryParameters:
                    query: queryValue
                defaultRequestHeaders:
                    header: headerValue
                requestInterceptors:
                    - com.example.FooRequestInterceptor
                    - com.example.BarRequestInterceptor
                decode404: false
                encoder: com.example.SimpleEncoder
                decoder: com.example.SimpleDecoder
                contract: com.example.SimpleContract
                capabilities:
                    - com.example.FooCapability
                    - com.example.BarCapability
                queryMapEncoder: com.example.SimpleQueryMapEncoder
                metrics.enabled: false

具体配置的使用可查看https://docs.spring.io/spring-cloud-openfeign/docs/current/reference/html/

4.feign-client调用过程

下面,我们从初始化到调用过程做详细的介绍。

4.1.FeignClient初始化为Spring bean过程

在spring cloud中,FeignClient是以单例形态存在的,也是一个Spring bean。初始化过程如下所示:

FeignClientsRegistrar#registerBeanDefinitions
	FeignClientsRegistrar#registerDefaultConfiguration
	FeignClientsRegistrar#registerFeignClients
		获取所有被@FeignClient注解的类,并针对每个类进行注册
		FeignClientsRegistrar#registerFeignClient
			BeanDefinitionBuilder#genericBeanDefinition
			设置BeanDefinition相关参数,这个BeanDefinition的指定的class类型是FeignClientFactoryBean
			BeanDefinitionReaderUtils#registerBeanDefinition

org.springframework.cloud.openfeign.FeignClientFactoryBean这个类实现了FactoryBean接口。spring在生成bean的时候,判断BeanDefinition中bean的class如果是FactoryBean的实现的话,会调用这个实现类的getObject来获取对象。

org.springframework.cloud.openfeign.FeignClientsRegistrar类实现了ImportBeanDefinitionRegistrar接口,ImportBeanDefinitionRegistrar主要用于实现“动态注册bean”功能,所有实现了该接口的类的都会被ConfigurationClassPostProcessor处理,ConfigurationClassPostProcessor实现了BeanFactoryPostProcessor接口,所以ImportBeanDefinitionRegistrar中动态注册的bean是优先与依赖其的bean初始化的,也能被aop、validator等机制处理。

4.2.FeignClient方法调用过程

如果想要调用feign api,首先需要获取对应的FeignClient bean。

4.2.1.FeignClient对象获取

上面说到,所有的FeignClient在spring容器中是以FeignClientFactoryBean身份存在的,如果要获取该FeignClient,比如通过@Autowired进行获取,则会调用FeignClientFactoryBean.getObject方法进行获取。

具体流程如下图所示:

Targeter有两个实现类:DefaultTargeter和FeignCircuitBreakerTargeter。

最终返回的是feign.ReflectiveFeign对象,ReflectiveFeign对象中包含各种FeignClient接口中方法的methodHandler,并通过Proxy.newProxyInstance创建代理对象的实例,代理方法的执行由FeignInvocationHandler类来实现。

4.2.2.FeignClient方法调用

方法调用时,由对应代理对象来实现,当调用FeignClient的某个方法时,会触发对应的InvocationHandler#invoke方法。具体的调用链路如下所示:

xxxFeignClient
feign.ReflectiveFeign.FeignInvocationHandler#invoke
feign.InvocationHandlerFactory.MethodHandler#invoke
feign.SynchronousMethodHandler#invoke
feign.SynchronousMethodHandler#executeAndDecode
org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient#execute
feign.Client.Default#execute
feign.AsyncResponseHandler#handleResponse