Spring Cloud Open Feign源码分析(上)

本文涉及的产品
网络型负载均衡 NLB,每月750个小时 15LCU
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: Spring Cloud Open Feign源码分析(上)

Open Feign(伪声明式RPC) 之所以称之为伪RPC,是因为它几乎和PRC的调用过程一样,像序列化,反序列化,动态代理之类的流程都有

面向接口的一种代理的封装,


思考Feign要做到的事情


参数的解析与装载

针对制定的feignClient,生成动态代理

针对FeignClient中的方法描述进行解析

组装出一个Request对象,发起请求


image.png


首先从@EnableFeignClients()注解进入@Import({FeignClientsRegistrar.class});

FeignClientsRegistrar类实现了ImportBeanDefinitionRegistrar接口;动态的将Bean装载到IOC容器中;


FeignClientsRegistrar类调用registerFeignClients();对于配置的package中可以能有多个FeignClient,用双重循环遍历不同路径下的不同的FeignClients和配置;


接着进入registerFeignClient()方法中;FeignClient被动态注册成一个FactoryBean

FactoryBean有一个特征,就是如果需要获得这个Bean的真正实例,会通过


FeignClientFactoryBean.getObject()中getTarget来获取最终实例,getTarget中会根据是否有URL,如果没有执行LoadBalancer负载均衡,否则进入下一个流程。


进入LoadBalancer方法的解析,其中有三个参数,FeignContext是代表Feign的上下文信息,


    protected <T> T loadBalance(Builder builder, FeignContext context, HardCodedTarget<T> target) {
        Client client = (Client)this.getOptional(context, Client.class);   //获取特定的实例的客户端
        if (client != null) {
            builder.client(client); //增加了请求的负载均衡的解析机制
            Targeter targeter = (Targeter)this.get(context, Targeter.class);
            return targeter.target(this, builder, context, target);  //target会有多种实现
        } else {
            throw new IllegalStateException("No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-netflix-ribbon?");
        }
    }


target有多种实现?


image.png


FeignAutoConfiguration自动装配类,自动装载FeignAutoConfigure.


image.png


Builder:


image.png


image.png


Client client = (Client)this.getOptional(context, Client.class);

getOptional通过获取FeignContext.getInstance(this.contextId, type); 针对某一个特定实例的上下文

image.png


builder.client(client);

相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
目录
相关文章
|
1月前
|
监控 Java 应用服务中间件
Spring Boot整合Tomcat底层源码分析
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置和起步依赖等特性,大大简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是其与Tomcat的整合。
61 1
|
2天前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
25天前
|
消息中间件 监控 Java
如何将Spring Boot + RabbitMQ应用程序部署到Pivotal Cloud Foundry (PCF)
如何将Spring Boot + RabbitMQ应用程序部署到Pivotal Cloud Foundry (PCF)
31 6
|
25天前
|
Java 关系型数据库 MySQL
如何将Spring Boot + MySQL应用程序部署到Pivotal Cloud Foundry (PCF)
如何将Spring Boot + MySQL应用程序部署到Pivotal Cloud Foundry (PCF)
45 5
|
25天前
|
缓存 监控 Java
如何将Spring Boot应用程序部署到Pivotal Cloud Foundry (PCF)
如何将Spring Boot应用程序部署到Pivotal Cloud Foundry (PCF)
35 5
|
1月前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
38 1
|
1月前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
35 1
|
2月前
|
缓存 JavaScript Java
Spring之FactoryBean的处理底层源码分析
本文介绍了Spring框架中FactoryBean的重要作用及其使用方法。通过一个简单的示例展示了如何通过FactoryBean返回一个User对象,并解释了在调用`getBean()`方法时,传入名称前添加`&`符号会改变返回对象类型的原因。进一步深入源码分析,详细说明了`getBean()`方法内部对FactoryBean的处理逻辑,解释了为何添加`&`符号会导致不同的行为。最后,通过具体代码片段展示了这一过程的关键步骤。
Spring之FactoryBean的处理底层源码分析
|
1月前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
30 0
|
3月前
|
Java API 开发者
【已解决】Spring Cloud Feign 上传文件,提示:the request was rejected because no multipart boundary was found的问题
【已解决】Spring Cloud Feign 上传文件,提示:the request was rejected because no multipart boundary was found的问题
727 0