0
点赞
收藏
分享

微信扫一扫

Spring Cloud OpenFegin(创建、发送请求)源码


感觉这一年来学习的知识点都是零零碎碎的,没有形成一个系统闭环,于是萌生了系统总结 Spring Cloud 源码相关的知识点的想法。后续会持续更新系统性的文章。纯原创,debug 总结。今天先简单debug下 OpenFegin 的创建吧。

Spring Cloud OpenFegin(创建、发送请求)源码_spring cloud

项目结构

标准的 SpringCloud 项目。

  • authservice:认证服务。Oauth2 那套认证逻辑
  • common:公共模块
  • gateway:网关模块
  • xxy-service-api:所有接口都写在这
  • xxy-service:所有接口实现类在这

Spring Cloud OpenFegin(创建、发送请求)源码_后端_02

user-api 定义了一个 getUser 接口

Spring Cloud OpenFegin(创建、发送请求)源码_后端_03

具体的 getUser 接口的实现是在认证服务里面(authservice)

Spring Cloud OpenFegin(创建、发送请求)源码_spring cloud_04

利用 OpenFegin 可以很轻松的实现,不同服务间接口的互相调用。接下来去看源码。

Spring Cloud OpenFegin(创建、发送请求)源码_动态代理_05


Spring Cloud OpenFegin(创建、发送请求)源码_负载均衡_06

分析 @FeignClient 注解

直接点击进入 FeignClient 所在的源码包里面分析,如下图,然后大概看到一个名字为 FeignClientFactoryBean 的类,毫不犹豫的点进去看 FeignClientFactoryBean 就行

Spring Cloud OpenFegin(创建、发送请求)源码_负载均衡_07

可以看到 FeignClientFactoryBean 还实现了Spring 提供的一些扩展方法: InitializingBean( populateBean 属性填充完成后,进行初始化 Bean)、ApplicationContextAware(用来获取Spring 上下文对象)、BeanFactoryAware。主要还是看和 FeignClientFactoryBean相关的就行。直接把 getObject 方法点到底就行。下面贴我 debug 的时序流程图,沿着圈红的方法点,嵌套这么多方法.

Spring Cloud OpenFegin(创建、发送请求)源码_动态代理_08

Spring Cloud OpenFegin(创建、发送请求)源码_负载均衡_09

Spring Cloud OpenFegin(创建、发送请求)源码_spring_10

Spring Cloud OpenFegin(创建、发送请求)源码_spring cloud_11

Spring Cloud OpenFegin(创建、发送请求)源码_spring cloud_12


Spring Cloud OpenFegin(创建、发送请求)源码_spring cloud_13

ok 点到底我们发现我们用到的Fegin 其实就是一个Jdk代理对象,里面织入了一个 InvocationHandler 的增强逻辑。每次我们调用Fegin 接口前,都会先掉 InvocationHandler 增强逻辑。到此 Fegin 的创建源码就结束了。

InvocationHandler handler = this.factory.create(target, methodToHandler);
    T proxy = Proxy.newProxyInstance(target.type().getClassLoader(), new Class[]{target.type()}, handler);
    Iterator var12 = defaultMethodHandlers.iterator();

小结OpenFegin创建流程

通过Spring 的 SPI功能扫描,将定义好的Fegin接口生成BeanDefinition(估计也是替换BeanClass为FactoryBean),然后利用 FactoryBean批量进行创建,然后通过Jdk动态代理,将增强逻辑织入到我们的Fegin代理对象中。具体细节没有进行细看,因为debug的过程中看到工厂Bean我就大概知道创建流程了。和我之前手写过的Mybatis动态生成Mapper的思想差不多。

手写 Mybatis-plus 基础架构(工厂模式+ Jdk 动态代理统一生成代理 Mapper)

OpenFegin参数组装源码

入口AbstractLoadBalancerAwareClient类下面的executeWithLoadBalancer方法。限于篇幅,中间的过程就不一一贴出来了,直接展示关键节点。

通过debug我们发现,当发起 http://localhost:9002/xxy-course/getUser 的请求后,最终经过lb负载均衡,会将请求转换成我们的真实请求地址http://192.168.11.101:8111/getUser

Spring Cloud OpenFegin(创建、发送请求)源码_后端_14

如何组装url的,源码位于LoadBalancerContext类下面的reconstructURIWithServer方法,没啥好看的,就是参数拼接。

Spring Cloud OpenFegin(创建、发送请求)源码_spring cloud_15

OpenFegin发送请求源码

通过debug,可以看到最终是调用FeignLoadBalancer下面的execute方法去发起的网络请求。

Spring Cloud OpenFegin(创建、发送请求)源码_spring cloud_16


中间过程有点多,直接贴debug时序图

Spring Cloud OpenFegin(创建、发送请求)源码_负载均衡_17


Spring Cloud OpenFegin(创建、发送请求)源码_动态代理_18

最终来到fegin.Client类下面的convertAndSend方法里面。通过抽丝剥茧可以看到fegin是默认是通过HttpURLConnection进行的发起网络请求。

Spring Cloud OpenFegin(创建、发送请求)源码_负载均衡_19

Spring Cloud OpenFegin(创建、发送请求)源码_spring_20


到此fegin的整个调用以及创建链路源码全部看完,其中的负载均衡、解码器部分的源码后续更新。

Spring Cloud OpenFegin(创建、发送请求)源码_spring_21


举报

相关推荐

0 条评论