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

发布时间:2024年01月09日

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

项目结构

标准的 SpringCloud 项目。

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

在这里插入图片描述

user-api 定义了一个 getUser 接口
在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述
在这里插入图片描述

分析 @FeignClient 注解

?
直接点击进入 FeignClient 所在的源码包里面分析,如下图,然后大概看到一个名字为 FeignClientFactoryBean 的类,毫不犹豫的点进去看 FeignClientFactoryBean 就行
?
在这里插入图片描述
?
可以看到 FeignClientFactoryBean 还实现了Spring 提供的一些扩展方法: InitializingBean( populateBean 属性填充完成后,进行初始化 Bean)、ApplicationContextAware(用来获取Spring 上下文对象)、BeanFactoryAware。主要还是看和 FeignClientFactoryBean相关的就行。直接把 getObject 方法点到底就行。下面贴我 debug 的时序流程图,沿着圈红的方法点,嵌套这么多方法.
?
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
?

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

在这里插入图片描述

如何组装url的,源码位于LoadBalancerContext类下面的reconstructURIWithServer方法,没啥好看的,就是参数拼接。
?在这里插入图片描述

OpenFegin发送请求源码

通过debug,可以看到最终是调用FeignLoadBalancer下面的execute方法去发起的网络请求。
在这里插入图片描述
中间过程有点多,直接贴debug时序图
在这里插入图片描述
在这里插入图片描述

最终来到fegin.Client类下面的convertAndSend方法里面。通过抽丝剥茧可以看到fegin是通过HttpURLConnection进行的发起网络请求,而不是我先前以为Fegin其实就是Httpclient的包装。小丑竟然是我自己
在这里插入图片描述

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

在这里插入图片描述

文章来源:https://blog.csdn.net/qq_42875345/article/details/135412566
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。