注册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接口运行过程大致分为如下几个步骤:
- @EnableFeignClient注解导入了FeignClientsRegistrar类。
- 执行FeignClientsRegistrar的registerBeanDefinitions()方法扫描basePackages中的Feign接口并为每个Feign接口注册FeignClientFactoryBean的BeanDefinition。
- Spring在实例化Feign接口时调用FeignClientFactoryBean类的getObject()方法返回Feign接口的代理实例。
- 创建InvocationHandler对象并使用JDK代理生成代理类。
- 如果引入了Hystrix的相关依赖则引入Hystrix的熔断模块(HystrixInvocationHandler)。
- 如果引入了Ribbon的相关依赖则Client接口会引入Ribbon的负载均衡模块(LoadBalancerFeignClient)。
- 发起Http调用,返回结果。
架构及核心流程
2022-03-24 17:47:46 补充:
Feign 主要是封装了 HTTP 请求调用,其整体架构如下:
Feign 的核心实现流程:从代码上看 SynchronousMethodHandler 的操作相对比较简单,主要是通过 client 完成请求,对响应进行解码以及异常处理操作,整体流程如下: