Spring Cloud Alibaba-Feign的源码分析2

简介: 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


相关实践学习
部署高可用架构
本场景主要介绍如何使用云服务器ECS、负载均衡SLB、云数据库RDS和数据传输服务产品来部署多可用区高可用架构。
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
1天前
|
Java 数据安全/隐私保护 Sentinel
微服务学习 | Spring Cloud 中使用 Sentinel 实现服务限流
微服务学习 | Spring Cloud 中使用 Sentinel 实现服务限流
|
2天前
|
Java API Nacos
第十二章 Spring Cloud Alibaba Sentinel
第十二章 Spring Cloud Alibaba Sentinel
12 0
|
2天前
|
监控 Java 微服务
第八章 Spring Cloud 之 Hystrix
第八章 Spring Cloud 之 Hystrix
|
2天前
|
监控 Java API
第七章 Spring Cloud 之 GateWay
第七章 Spring Cloud 之 GateWay
|
2天前
|
负载均衡 前端开发 Java
第六章 Spring Cloud 之 OpenFeign
第六章 Spring Cloud 之 OpenFeign
|
2天前
|
消息中间件 Java Nacos
第三章 Spring Cloud简介
第三章 Spring Cloud简介
|
2天前
|
Java Nacos 开发者
Java从入门到精通:4.2.1学习新技术与框架——以Spring Boot和Spring Cloud Alibaba为例
Java从入门到精通:4.2.1学习新技术与框架——以Spring Boot和Spring Cloud Alibaba为例
|
2天前
|
Dubbo Java 应用服务中间件
Java从入门到精通:3.2.2分布式与并发编程——了解分布式系统的基本概念,学习使用Dubbo、Spring Cloud等分布式框架
Java从入门到精通:3.2.2分布式与并发编程——了解分布式系统的基本概念,学习使用Dubbo、Spring Cloud等分布式框架
|
9天前
|
负载均衡 Java 开发者
细解微服务架构实践:如何使用Spring Cloud进行Java微服务治理
【4月更文挑战第17天】Spring Cloud是Java微服务治理的首选框架,整合了Eureka(服务发现)、Ribbon(客户端负载均衡)、Hystrix(熔断器)、Zuul(API网关)和Config Server(配置中心)。通过Eureka实现服务注册与发现,Ribbon提供负载均衡,Hystrix实现熔断保护,Zuul作为API网关,Config Server集中管理配置。理解并运用Spring Cloud进行微服务治理是现代Java开发者的关键技能。
|
10天前
|
Java API 对象存储
对象存储OSS产品常见问题之使用Spring Cloud Alibaba情况下文档添加水印如何解决
对象存储OSS是基于互联网的数据存储服务模式,让用户可以安全、可靠地存储大量非结构化数据,如图片、音频、视频、文档等任意类型文件,并通过简单的基于HTTP/HTTPS协议的RESTful API接口进行访问和管理。本帖梳理了用户在实际使用中可能遇到的各种常见问题,涵盖了基础操作、性能优化、安全设置、费用管理、数据备份与恢复、跨区域同步、API接口调用等多个方面。
26 2