文章

Feign源码分析

本文深入剖析Feign微服务框架的工作原理,包括如何通过@EnableFeignClients注解激活Feign功能,利用JDK代理生成RequestTemplate,以及通过HttpClient、OkHttp进行HTTP请求。同时,详细介绍了Feign如何结合Ribbon实现负载均衡。

Feign源码分析

文章信息

  • 原文链接: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做到了负载均衡。
本文由作者按照 CC BY 4.0 进行授权