Feign源码分析
本文深入剖析Feign微服务框架的工作原理,包括如何通过@EnableFeignClients注解激活Feign功能,利用JDK代理生成RequestTemplate,以及通过HttpClient、OkHttp进行HTTP请求。同时,详细介绍了Feign如何结合Ribbon实现负载均衡。
文章信息
- 原文链接:https://jiayq.blog.csdn.net/article/details/104542555
- 发布时间:2020-03-01 16:02:30
- 阅读量:563
- 分类:微服务同时被 2 个专栏收录, 订阅专栏, spring boot
- 标签:#Feign工作原理, #Feign源码解析, #Feign与HttpUrlC, #Feign与HttpClt, #Feign与OkHttp
摘要
文章浏览阅读563次。本文深入剖析Feign微服务框架的工作原理,包括如何通过@EnableFeignClients注解激活Feign功能,利用JDK代理生成RequestTemplate,以及通过HttpClient、OkHttp进行HTTP请求。同时,详细介绍了Feign如何结合Ribbon实现负载均衡。
Feign源码分析
- 1. Feign工作原理
- 2. Feign使用HttpClient和OkHttp
- 3. Feign是如何实现负载均衡
git地址
https://github.com/a18792721831/studySpringCloud.git
1. Feign工作原理
项目需要集成Feign,那么就需要在main方法对应的类上加上Feign开启的注解@EnableFeignClients
进入@EnableFeignClients注解

FeignClientsRegistrar

会进行一些处理

Feign 通过包扫描注入 FeignClient 的 Bean,该源码在FeignClientsRegistrar类中。首先在程序启动时,会检查是否有@EnableFeignClients注解,如果有该注解,则开启包扫描,扫描被@FeignClient 注解的接口。

通过断点调试,当程序的启动类上有@EnablefeignClients 注解。在程序启动后,程序会通过包扫描将有
@FegaClient注解修饰的接口连同接口名和注解的信息一起取出,赋给 BeanDefinitionBuilde然后根据BeanDefnitionBuilder 得到BeanDefinition,最后将 BeanDefinition 注入IoC 容器中。


注入BeanDefinition之后,通过JDK的代理,当调用Feign Cleint接口里面的方法时,该方法会被拦截。


在SynchronousMethodHandler类进行拦截处理,会根据参数生成RequestTemplate对象,该对象是Http请求的模板。

executeAndDecode方法通过RequestTemplate生成Reques请求对象,然后用Http Client获取Rqsponse,即通过Http Client进行Http请求获取响应。

2. Feign使用HttpClient和OkHttp
首先查看FeignRibbonClient的自动配置类,该类在工程启动时注入一些Bean,其中注入了一个BeanName为FeignClient的Bean


在缺省配置BeanName为FeignClient的Bean的情况下,会自动注入Client.Default这个对象。

我们刚才看了默认的配置,上面之前Import还有其他两个类

这是HttpClient

发现代码提示异常,是ApacheHttpClient的依赖未找到。
所以,只需要我们加入这个依赖就能使用HttpClient作为Feign的请求。

从@ConditionalOnProperty中看出,需要在配置文件将feign.httpclient.enabled设置为true.当然,也可以不写,默认为true
接下来看OkHttp

OkHttp上面的注解就没有默认值了,所以OkHttp就需要配置了,

因为默认是false.

3. Feign是如何实现负载均衡
当程序的启动类上有@EnablefeignClients 注解。在程序启动后,程序会通过包扫描将有@FegaClient注解修饰的接口连同接口名和注解的信息一起取出,赋给 BeanDefinitionBuilde然后根据BeanDefnitionBuilder 得到BeanDefinition,最后将 BeanDefinition 注入IoC 容器中。

其中有一个executeWithLoadBalancer方法,通过负载均衡的方式执行网络请求。

进入commit方法,,内部是LoadBalancerCommand的方法

selectServer方法就是选择服务进行负载均衡

到了这里,又到了RibbonLoadBalancer的loadBalancerContext进行处理,即交由Ribbon进行处理了。
总的来说,Feign的源码实现过程如下。
- (1)首先通过@EnableFeignClients 注解开启 FeignClient的功能。只有这个注解存在,才会在程序启动时开启对@FeignClient注解的包扫描。
- (2)根据Feign的规则实现接口,并在接口上面加上@FcignClient注解。
- (3)程序启动后,会进行包扫描,扫描所有的@ FeignClient 的注解的类,并将这些信息注入IoC 容器中。
- (4)当接口的方法被调用时,通过JDK 的代理来生成具体的 RequestTemplate 模板对象。
- (5)根据 RequestTemplate 再生成 Http 请求的 Request对象。
- (6)Request 对象交给 Client 去处理,其中 Client 的网络请求框架可以是 HttpURLConnection、HttpClient 和 OkHttp。
- (7)最后Client被封装到LoadBalanceClient类,这个类结合类Ribbon做到了负载均衡。