SpringCloud--OpenFeign解析

一、OpenFeign简介

OpenFeign是一个声明式的Web服务客户端,它简化了与HTTP API的通信。它的底层原理主要基于Java的反射和动态代理,并且通过利用Spring AOP 框架、RestTemplate、Ribbon 和 Hystrix 等组件,将复杂的 HTTP 调用封装起来,使得开发者能够像调用本地服务一样使用远程服务。

二、OpenFeign 使用步骤

假设有个下单服务为orderService需要调用库存服务stockService中的接口查询商品的库存量。

  1. 首先在两个服务的pom.xml文件中引入OpenFeign 组件。
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
  1. 先在orderService创建一个查询商品库存的接口,这个接口上面使用了一个@FeignClient注解标注,注解里面的name属性指定了要调用的服务名,表明该远程接口属于哪个服务。接口里面的方法上面使用了@RequestMapping注解标注,该注解里面指定了要访问的接口路径。
@FeignClient(name = "stock-service")
public interface StockServiceFeign {/*** 获取商品信息**/@RequestMapping("/stock/getStockInfo")CommonResult<Page<SysRole>> getStockInfo(@RequestParam String stockId);
}
  1. 在orderService的启动类上添加@EnableFeignClients注解,该注解表明在服务启动后开启远程调用。
@EnableFeignClients
@SpringBootApplication
public class NjhGatewayApplication {public static void main(String[] args) {SpringApplication.run(NjhGatewayApplication.class, args);}
}
  1. 最后到stockService服务中定义一个接口去实现具体的功能,并保证接口地址以及入参与orderService刚定义的接口一致。
@RestController
public class StockController {@Autowired StockService;@RequestMapping("/stock/getStockInfo")public R getStockInfo(@RequestParam String stockId) {return StockService.getStockInfo(stockId);}
}

三、实现原理

从上面例子可以看出OpenFeign 使用起来还是很简单方便,但是其底层原理就没那么简单了。其核心的处理逻辑就是使用Spring的AOP动态代理技术,对所有被 @FeignClient 注解修饰的接口生成一个动态代理类,在这个代理类中会将注解中的服务的名称、接口类型、访问路径转化成一个远程服务调用的 Request请求,并发送给目标服务。转化后的Request请求格式类似GET http://stock-service/stock/getStockInfo/10001 HTTP/1.1,下面看下主要的处理流程:

  1. 创建代理对象:当你定义一个使用了 @FeignClient 注解的接口时,OpenFeign 会在运行时为这个接口创建一个代理对象。这个代理对象用于处理对远程服务的调用。
  2. 解析注解:在运行时,OpenFeign 会解析 @FeignClient 注解,确定要连接的服务名称。如果使 用了服务注册中心(如 Eureka),服务名称会被用来查找服务实例。
  3. 路由匹配:对于每个接口方法,OpenFeign 会创建一个映射,将方法路径(如果提供的话)和 HTTP 请求方法(如 GET、POST 等)与服务端的 API 路径进行匹配。
  4. 构建请求:当代理对象被调用时,OpenFeign 会构建一个 HTTP 请求,这个请求包含了方法参数作为请求体或查询参数。编码器将这些参数转换为适用于 HTTP 传输的格式。
  5. HTTP 调用:使用默认的或自定义的 HTTP 客户端,OpenFeign 发送 HTTP 请求到远程服务。如果使用了 Ribbon,它会进行负载均衡来决定请求发送到哪个服务实例。
  6. 接收响应:HTTP 客户端接收远程服务的响应,并将其传递给解码器。
  7. 解码响应:解码器将 HTTP 响应体解码为方法可以接受的参数或返回值。如果响应是一个 JSON 或 XML 字符串,解码器会将其转换为 Java 对象。
  8. 处理异常:如果在请求过程中发生错误,例如连接失败或解码错误,OpenFeign 会将异常传递给调用者。开发者可以定义错误处理策略来处理这些异常。
  9. 返回结果:最终,解码后的结果会作为方法的返回值返回给调用方。

四、源码解析

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({FeignClientsRegistrar.class})
public @interface EnableFeignClients {String[] value() default {};String[] basePackages() default {};Class<?>[] basePackageClasses() default {};Class<?>[] defaultConfiguration() default {};Class<?>[] clients() default {};
}

(1)@EnableFeignClients注解中的basePackages属性来设置包扫描的范围,从中找出所有带有@FeignClient 注解的类、接口,并将它们注册为Feign客户端。

@EnableFeignClients(basePackages = "com.jackson0714.passjava.member.feign")

(2)进入@EnableFeignClients注解可以看到里面使用了一个@Import({FeignClientsRegistrar.class})注解,里面还导入了FeignClientsRegistrar.class类,主要负责将Feign Client的Bean注册到Spring的IOC容器中。
在这里插入图片描述
(3)registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry)方法主要用于注册Bean定义。
在这里插入图片描述
(4)getBasePackages(AnnotationMetadata importingClassMetadata)方法将扫描到的所有@FeignClient 注解的元数据,从这些元数据中提取出基础包名,并将它们作为一个Set集合返回。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/439595.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

游泳耳机哪个牌子好?游泳耳机型号排行榜单帮你选!

游泳是一项绝佳的全身运动&#xff0c;不仅可以增强体能&#xff0c;还能锻炼身体、减轻压力。然而&#xff0c;在游泳的时候&#xff0c;我们常常感到无聊&#xff0c;缺乏动力。怎么办呢&#xff1f;这时一个出色的游泳耳机就显得尤为重要。今天&#xff0c;我将向大家介绍一…

Redis 面试题 | 19.精选Redis高频面试题

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

【三维重建】运动恢复结构(SfM)

运动恢复结构是通过三维场景的多张图像&#xff0c;恢复出该场景的三维结构信息以及每张图片对应的摄像机参数。 欧式结构恢复(内参已知&#xff0c;外参未知) 欧式结构恢复问题&#xff1a; 已知&#xff1a;1、n个三维点在m张图像中的对应点的像素坐标 2、相机内参 求解&…

07. STP的基本配置

文章目录 一. 初识STP1.1. STP概述1.2. STP的出现1.3. STP的作用1.4. STP的专业术语1.5. BPDU的报文格式1.6. STP的选择原则&#xff08;1&#xff09;选择根桥网桥原则&#xff08;2&#xff09;选择根端口原则 1.7. 端口状态1.8. STP报文类型1.9. STP的收敛时间 二. 实验专题…

idea 创建 spring boot

1.创建步骤 2. 编码添加 2.1 这是自动生成的启动函数 package com.example.comxjctest4;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;SpringBootApplication public class Application {publi…

电脑文件丢失怎么恢复数据?数据恢复,3个方法!

“我有一份很重要的资料文件保存在电脑上了&#xff0c;但是刚刚发现这些文件莫名其妙丢失了。电脑文件丢失应该怎么恢复数据呀&#xff1f;大家有什么比较好用的方法可以推荐吗&#xff1f;” 在日常生活中&#xff0c;我们经常都需要使用电脑&#xff0c;当然&#xff0c;也会…

【算法】BFS算法解决多源最短路问题(C++)

文章目录 前言那么什么是单源最短路 / 多源最短路呢&#xff1f;如何解决此类题&#xff1f;解法一解法二对于解法二&#xff0c;如何编写代码&#xff1f; 算法题542.01矩阵1020.飞地的数量1765.地图中的最高点1162.地图分析 前言 此前我们对 单源最短路 问题进行的讲解&…

Orion-14B-Chat-Plugin本地部署的解决方案

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

Unity3d实现简单的战斗

使用u3d实现一个简单的战斗demo&#xff0c;记下学到的知识点&#xff0c;以备后查。 1.判断鼠标是否点中制定物体 if (Input.GetMouseButton(0)) {Ray ray Camera.main.ScreenPointToRay(Input.mousePosition);if (Physics.Raycast(ray, out RaycastHit hit)){//坐标转换Ve…

Hexo上传html文件失败

✅作者简介&#xff1a;CSDN内容合伙人、信息安全专业在校大学生&#x1f3c6; &#x1f525;系列专栏 &#xff1a;零基础搭建博客 &#x1f4c3;新人博主 &#xff1a;欢迎点赞收藏关注&#xff0c;会回访&#xff01; &#x1f4ac;舞台再大&#xff0c;你不上台&#xff0c…

世界坐标系转换为平面地图坐标

将世界坐标系转换为平面地图坐标的方法通常涉及地图投影。地图投影是一种将地球(一个三维球体)上的点转换为平面(二维)地图上的点的方法。 这里介绍几种常见的地图投影方法: 墨卡托投影(Mercator Projection): 这是最常见的投影方式之一,尤其用于航海地图。它将经纬度…

实现vue3响应式系统核心-增强对象拦截

简介 在之前的文章中我们实现一个响应式系统的 MVP 模型&#xff0c;也实现了 computed 、watch 等。 今天再来看看对于对象的拦截&#xff0c;我们思考以下几个问题&#xff1a; 如何拦截 in操作符呢&#xff1f;如何拦截 for in 循环呢&#xff1f;如何拦截对象的删除操作呢…