当前位置: 首页 > article >正文

OpenFeign原理

文章目录

      • 概要
      • 原理概述
      • OpenFeign 的基本使用
      • 核心注解和功能
      • 源码解析流程
        • @FeignClient 的解析
        • Feign 动态代理的实现
        • 请求的执行与负载均衡
        • 结果的解码(Decoder)
      • 总结

概要

Spring Cloud OpenFeign 是 Spring Cloud 中用于实现声明式 HTTP 客户端的组件。通过它,可以使用类似调用本地方法的方式调用远程 HTTP 服务,极大地简化了微服务架构中服务之间的通信。

原理概述

OpenFeign 的原理主要涉及通过代理类将服务名称替换为具体的 IP:端口 来实现远程服务调用。

  • Feign 生成代理类:使用 JDK 动态代理为 @FeignClient 接口生成代理,拦截接口方法调用,构建 HTTP 请求。
  • 服务名称替换为 IP:端口:Feign 会将服务名称(如 serviceA)通过 Ribbon 进行解析,将其替换为对应的 IP:端口
  • 负载均衡:Ribbon 在服务发现的基础上,对多个服务实例进行负载均衡,选择一个合适的服务实例。
  • 发送 HTTP 请求:最终由 Feign 发起 HTTP 请求,调用远程服务并返回结果。

OpenFeign 的基本使用

@FeignClient(name = "serviceA") // 指定服务名称
public interface ServiceAClient {
    @GetMapping("/api/data")
    String getData();
}

通过注解 @FeignClient,我们定义了一个远程调用接口 ServiceAClient,并通过 getData() 方法发起 GET 请求。Feign 会根据这个接口生成动态代理,并执行远程调用。

核心注解和功能

  • @FeignClient:这个注解用于定义一个 Feign 客户端接口,主要是用来标识接口为 Feign 客户端。
  • @EnableFeignClients:这个注解用于启动 Feign 客户端功能,通常在 Spring Boot 启动类上添加。
@EnableFeignClients
@SpringBootApplication
public class FeignExampleApplication {
    public static void main(String[] args) {
        SpringApplication.run(FeignExampleApplication.class, args);
    }
}

源码解析流程

@FeignClient 的解析

@FeignClient 注解是 Feign 的核心,它定义了远程调用的接口。FeignClient 在 Spring Boot 启动时会被扫描,并注册为 Spring 容器中的 Bean。具体流程如下:

  1. FeignClientsRegistrar
    在这里插入图片描述

在这里插入图片描述

  • @FeignClient 注解的解析工作由 FeignClientsRegistrar 类完成。FeignClientsRegistrar 实现了 ImportBeanDefinitionRegistrar 接口(
    ImportBeanDefinitionRegistrar 用于在运行时动态地向 Spring 容器中注册 Bean 定义。)
    在这里插入图片描述

  • FeignClientsRegistrar 类中的 registerBeanDefinitions() 方法中,它扫描带有 @FeignClient 的接口,解析并注册这些接口对应的 Feign 客户端 Bean。

	@Override
	public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
		registerDefaultConfiguration(metadata, registry);
		registerFeignClients(metadata, registry); // 细看源码
	}
  1. FeignClientFactoryBean

    • 每一个 @FeignClient 注解都会生成一个 FeignClientFactoryBean,该类实现了 FactoryBean 接口,用于动态创建 Feign 客户端。
    • FeignClientFactoryBeangetObject() 方法中会返回一个动态代理类,这个代理类负责将接口调用转化为 HTTP 请求。
     @Override
     public Object getObject() {
     	return getTarget(); // 可自己看看源码
     }
    
Feign 动态代理的实现

Feign 本质上是一个基于 JDK 动态代理的 HTTP 客户端。每次调用接口方法时,都会通过动态代理拦截调用,并将其转换为 HTTP 请求。
在这里插入图片描述

  1. 代理的创建
    ReflectiveFeign 继承 Feign 类,ReflectiveFeign 使用 JDK 的 Proxy.newProxyInstance() 方法为标注了 @FeignClient 的接口生成一个代理对象。

  2. FeignInvocationHandler
    每次调用接口时,代理对象会调用 FeignInvocationHandlerinvoke() 方法。该方法中,Feign 会根据接口的注解(如 @GetMapping 等)构建 HTTP 请求,并通过 Client 发送请求。

  3. MethodHandler
    MethodHandler 是一个接口,具体的实现类 SynchronousMethodHandler 负责将方法调用转化为 HTTP 请求,并处理返回结果。

请求的执行与负载均衡
  1. 请求的执行
    Feign 的 Client 接口负责发送 HTTP 请求,默认情况下使用 HttpURLConnection 作为底层 HTTP 客户端。也可以集成 OkHttpApache HttpClient 等其他 HTTP 客户端。

  2. 负载均衡
    在 Spring Cloud 中,Feign 可以与 Ribbon(客户端负载均衡器)集成。当 Feign 调用服务时,Ribbon 会根据配置自动选择一个服务实例,从而实现客户端的负载均衡。

    Feign 的 LoadBalancerFeignClient 包装了原始的 Feign Client,负责从 Ribbon 中获取服务实例并执行请求:

结果的解码(Decoder)

Feign 的 Decoder 接口负责将 HTTP 响应转换为方法的返回值。默认的 Decoder 使用 JacksonGson 来将 JSON 响应解析为对象。你可以通过配置自定义的 Decoder 来改变这个行为。

总结

Spring Cloud OpenFeign 通过一系列注解和动态代理机制将接口调用转化为 HTTP 请求,简化了微服务之间的通信。其核心流程可以总结为以下几个步骤:

  1. @FeignClient 注解标注的接口会在应用启动时被扫描并注册为 Spring Bean。
  2. FeignClientFactoryBean 创建 Feign 客户端的动态代理对象。
  3. Feign 的动态代理将接口方法调用拦截,并通过 FeignInvocationHandler 转化为 HTTP 请求。
  4. 请求通过 Client 发出,可以与 Ribbon 集成实现负载均衡。
  5. 返回结果由 Decoder 解析为对应的 Java 对象。

❤觉得有用的可以留个关注~❤


http://www.kler.cn/a/302286.html

相关文章:

  • 【论文阅读】Virtual Compiler Is All You Need For Assembly Code Search
  • C语言打印时间精确到毫秒
  • ESLint 使用教程(五):ESLint 和 Prettier 的结合使用与冲突解决
  • [JAVAEE] 面试题(四) - 多线程下使用ArrayList涉及到的线程安全问题及解决
  • C++STL容器——map和set
  • AI大模型开发架构设计(18)——基于大模型构建企业知识库案例实战
  • docker-ce.repo源、kubernetes.repo源
  • 通过AI来创建一个_____html css网页制作成品 例子演示
  • 精准电商营销:基于京东商品详情API返回值的数据分析
  • 探索Python中的链式赋值、系列解包赋值与常量
  • Vue.js中computed的使用方法
  • Minio笔记-Centos搭建Minio
  • pgAdmin 4备份数据库失败,解决
  • 武汉墨家人俱乐部
  • 计算机毕业设计选题推荐-校园车辆管理系统-Java/Python项目实战(亮点:数据可视化分析、账号锁定)
  • 如何为 MongoDB 3.0.4 以下版本选择合适的 PyMongo 版本
  • 第10章 中断和动态时钟显示
  • 零基础5分钟上手亚马逊云科技-为网站服务器配置DNS域名
  • 基础的八股
  • Go语言现代Web开发03 关键字和包以及基本数据类型
  • word文档无损原样转pdf在windows平台使用python调用win32com使用pip安装pywin32
  • PHP精准投放高效转化微信代金券发券系统小程序源码
  • QuecPythonHeliosSDK 使用介绍
  • 借助ChatGPT撰写学术论文的10条规则
  • android studio 模拟器 loadlibrary failed with 126:找不到指定的模块
  • 数据处理与统计分析篇-day02-Linux进阶