Feign 源码解析

注册BeanDefinition

在这里插入图片描述

实例化代理对象

已经把要创建的接口代理对象的信息放入registry里面,之后Spring在启动调用refresh()方法的时候会负责bean的实例化。
在实例化过程中,调用FeignClientFactoryBean的getObject()方法。
在这里插入图片描述

》》》补充一句:
调用loadBalance()方法,此方法会从Spring上下文中找Client和Targeter并调用Targeter的target()方法生成代理对象,Targeter的实现类有两个:DefaultTargeter和HystrixTargeter。

DefaultTargeter的target()方法直接调用Feign.Builder的target()方法返回对象实例。
HystrixTargeter的target()方法会根据Feign接口配置以及Feign.Builder的类型来决定调用DefaultTargeter的target()还是HystrixTargeter的target()返代理对象。

在引入Hystrix相关依赖后就会使用HystrixTargeter。

feign:invoke

在SynchronousMethodHandler类进行拦截处理,当被拦截会根据参数生成RequestTemplate对象,该对象就是http请求的模板,然后调用executeAndDecode()方法,该方法通RequestTemplate生成Request请求对象,然后根据用client获取response。
在这里插入图片描述

默认客户端问题

关于默认客户端问题,补充一句:
Client组件是一个非常重要的组件,Feign最终发送request请求以及接收response响应,都是由Client组件完成的,其中Client的实现类,只要有Client.Default,该类由HttpURLConnnection实现网络请求,另外还支持HttpClient、Okhttp。
在这里插入图片描述

lb:selectServer and execute

关于下面的代码不用去纠结,只是一个 reactivex 响应式编程。
在这里插入图片描述

RoundRobinRule:choose

可参考之前的一张图片:Ribbon 负载均衡算法

总结

Feign接口运行过程大致分为如下几个步骤:

  1. @EnableFeignClient注解导入了FeignClientsRegistrar类。
  2. 执行FeignClientsRegistrar的registerBeanDefinitions()方法扫描basePackages中的Feign接口并为每个Feign接口注册FeignClientFactoryBean的BeanDefinition。
  3. Spring在实例化Feign接口时调用FeignClientFactoryBean类的getObject()方法返回Feign接口的代理实例。
  4. 创建InvocationHandler对象并使用JDK代理生成代理类。
  5. 如果引入了Hystrix的相关依赖则引入Hystrix的熔断模块(HystrixInvocationHandler)。
  6. 如果引入了Ribbon的相关依赖则Client接口会引入Ribbon的负载均衡模块(LoadBalancerFeignClient)。
  7. 发起Http调用,返回结果。

架构及核心流程

2022-03-24 17:47:46 补充:

Feign 主要是封装了 HTTP 请求调用,其整体架构如下:
在这里插入图片描述

Feign 的核心实现流程:从代码上看 SynchronousMethodHandler 的操作相对比较简单,主要是通过 client 完成请求,对响应进行解码以及异常处理操作,整体流程如下:
请添加图片描述