Spring Cloud Alibaba-Feign的源码分析2

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
EMR Serverless StarRocks,5000CU*H 48000GB*H
简介: Spring Cloud Alibaba-Feign的源码分析2

4、FeignClientFactoryBean创建动态代理


由于FeignClientFactoryBean是tFactoryBean所有获取对象是从getObject中

image.png

image.png


4.1 获取组件属性


从容器中获取对应的FeignContext,

image.png


我们进入feign(contex)

image.png

这些方法都是调用的get方法,只是类型不同而已

image.png

image.png

image.pngimage.png

image.png


image.png

在getObject⽅法中,⾸先从applicationContext中、也就是从Spring容器中获取了⼀个FeignContext组件,应该是Feign存放⼯具类的⼀个上下⽂组件,然后从FeignContext中获取到了FeignLoggerFactory组件,⼀路追进去发现,原来在底层也是维护了⼀个Spring容器的缓存Map<String, AnnotationConfigApplicationContext>。


Feign在执⾏时涉及到⼀系列的组件,所以Feign⼲脆为每个服务创建了⼀个Spring容器类ApplicationContext,⽤来存放每个服务各⾃所需要的组件,每个服务的这些⼯具类、组件都是互不影,所以我们看到它在底层是通过⼀个Map来缓存的,key为服务名,value为服务所对应的的spring容器ApplicationContext。


接着我们想不管是FeignContext、FeignLoggerFactory还是Encoder、Decoder、Contract,他们都是接⼝,那具体的实现类是什么呢?


因为它们都是直接从Spring的容器中取出来的,这就意味着在某个地⽅事先注⼊到了Spring容器中了,所以我们还得从⼀些地⽅、如配置类⾥⾯看下。


在SpringCloud系列组件中,设计者都⽐较喜欢把⼀些组件的初始化都放在⼀些XxxConfiguration中,然后需要使⽤到的时候通过容器直接取,但是对于我们分析⽽⾔、还是有点麻烦的,毕竟还得去找。


⾸先因为我们当前是在FeignClientFactoryBean中,所以⾸先当然是从它对应路径下开始寻找,看下有没有类似Configuration相关的类,如下图所示:


FeignAutoConfiguration


image.png

FeignClientsConfiguration

image.png

上面是对应get内容


下面对应configureFeign


image.png

我们看方法会发现里面就是先获取java类配置,然后再获取属性配置,属性配置会把代码配置给覆盖掉,所以我们需要属性配置优先级高于代码


image.png

4.2 创建动态代理对象


因为@FeignClient默认属性是name,所以url为空,所以第一个if条件成立;而注解中name属性值是msb-stock,所以url最后为http://msb-stock然后进⼊loadBalance⽅法中,从⽅法名称上来看、从这⾥开始要和负载均衡有点关系了。

image.png


获取的Client是LoadBalanceFeignClient,对应的Targeter是HystrixTargeter

image.png


创建实例

image.png

创建动态代理的类。

image.png

在newInstance⽅法中,⼀开始先调⽤targetToHandlersByName获取了Map<String, MethodHandler>,因为我们这⾥是动态代理、⽽且代理的是接⼝的⽅法,所以我们基本可以猜测到这⾥是想要为每个⽅法创建⼀个⽅法的处理器,也就是MethodHandler,但是具体怎么创建呢?


image.png

我们进入factory.create查看是怎样创建MethodHandler


这里重点就是我们会把我们对应的接口封装为<font


color="red">SynchronousMethodHandler</font>,后面调用的时候我们会进入这个方法

image.png

理解了前⾯的内容之后,现在就⽐较好理解了,创建动态代理、怎么代理呢,就是遍历了下⽅法,把之前的Map<String, MethodHandler>、本来以⽅法名称为key的形式、换成了以Method为key的methodToHandler的Map<Method, MethodHandler>。

⽅便通过Method就能从Map获取到对应的Handler,然后创建了InvocationHandler,通过JDK的API 创建⼀个JDK的动态代理并返回。


好,我们查看创建jdk动态代理InvocationHandler

image.png

=image.png

到这⾥我们基本上可以知道:⽐如当服务B的getById⽅法被调⽤时、会调⽤服务A的getById⽅法,⽽服务A这⾥因为是通过Feign声明式调⽤的,肯定会先通过服务A的Feign动态代理FeignInvocationHandler,从动态代理中的Map<Method, MethodHandler>中、找到具体某个⽅法的SynchronousMethodHandler,然后执⾏该SynchronousMethodHandler中的invoke⽅法来处理⽅法的逻辑。


并且根据我们最早的猜测,SynchronousMethodHandler中的逻辑⽆⾮就是将前⾯从@FeignClient、接⼝上的@RequestMapping、@PathVariable、@RequestParams等注解中解析到的信息,拼凑成⼀个完整的HTTP请求,然后发起请求并接对应的响应信息。


4.3 进行调用


jdk动态代理的调用,会调用FeignInvocationHandler.invoke


从缓存中通过Method获取对应的MethodHandler (SynchronousMethodHandler

image.png

image.png

然后调用SynchronousMethodHandler

image.png

这里通过client进行执行,这里面应该有负载均衡和调用

image.png

image.png

4.3.1 获取负载均衡器

image.png

image.png


image.png

4.3.2通过负载均衡器获取服务

image.png


LoadBalancerCommand从名称可以推测这是一个负载均衡器,调用submit里面会调用selectServer方法
复制代码


image.png

image.png

image.png

获取负载均衡器ZoneAwareLoadBalancer,然后根据路由规则进行调用这里就是ribbon的内容了

image.png

4.3.3 重构URL

image.png

可以进入看一下就是拼接字符串

image.png

4.3.4 发送http请求

image.png

image.png

默认我们会调用最后HttpUrlConnection

image.png

image.png


相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
3天前
|
监控 Java 应用服务中间件
Spring Boot整合Tomcat底层源码分析
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置和起步依赖等特性,大大简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是其与Tomcat的整合。
19 1
|
18天前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
28 1
|
19天前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
25 1
|
1月前
|
缓存 JavaScript Java
Spring之FactoryBean的处理底层源码分析
本文介绍了Spring框架中FactoryBean的重要作用及其使用方法。通过一个简单的示例展示了如何通过FactoryBean返回一个User对象,并解释了在调用`getBean()`方法时,传入名称前添加`&`符号会改变返回对象类型的原因。进一步深入源码分析,详细说明了`getBean()`方法内部对FactoryBean的处理逻辑,解释了为何添加`&`符号会导致不同的行为。最后,通过具体代码片段展示了这一过程的关键步骤。
Spring之FactoryBean的处理底层源码分析
|
16天前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
21 0
|
4月前
|
负载均衡 Java Spring
Spring cloud gateway 如何在路由时进行负载均衡
Spring cloud gateway 如何在路由时进行负载均衡
488 15
|
4月前
|
Java Spring
spring cloud gateway在使用 zookeeper 注册中心时,配置https 进行服务转发
spring cloud gateway在使用 zookeeper 注册中心时,配置https 进行服务转发
111 3
|
4月前
|
消息中间件 Java Nacos
通用快照方案问题之通过Spring Cloud实现配置的自动更新如何解决
通用快照方案问题之通过Spring Cloud实现配置的自动更新如何解决
76 0
|
4月前
|
缓存 监控 Java
通用快照方案问题之Spring Boot Admin的定义如何解决
通用快照方案问题之Spring Boot Admin的定义如何解决
62 0
|
4月前
|
监控 NoSQL Java
通用快照方案问题之Martin Flower提出的微服务之间的通信如何解决
通用快照方案问题之Martin Flower提出的微服务之间的通信如何解决
42 0