使用Feign进行微服务之间的接口调用:Spring Cloud Alibaba中的声明式服务调用

news2024/10/6 6:41:45

一、Feign介绍

        Feign是一个声明式的HTTP客户端框架,用于简化微服务架构中服务之间的通信。它是Spring Cloud框架的一部分,旨在提供一种优雅且易于使用的方式来定义和调用HTTP请求。

        Feign的设计目标是让服务之间的通信变得更加简单和直观。通常情况下,在微服务架构中,一个服务需要调用另一个服务的API来获取数据或执行操作。使用传统的方式,我们需要手动编写HTTP请求、处理请求和响应等操作,而Feign的出现简化了这个过程。

        使用Feign,只需定义一个接口来描述要调用的服务的API,然后通过注解来配置请求和响应的处理方式。Feign会根据接口定义自动生成可用的HTTP请求,将请求发送到目标服务,并将响应转换为适当的对象类型返回。

Feign具有以下特性和优势:

  1. 声明式的API定义:通过简单地定义接口,可以清晰地描述服务之间的通信,而不必关注底层的HTTP细节。
  2. 内置负载均衡支持:Feign与Spring Cloud的服务注册和发现机制集成,可以自动实现负载均衡,轻松处理多个实例的服务调用。
  3. 请求和响应的自动序列化和反序列化:Feign可以自动处理请求和响应的序列化和反序列化,使您能够以面向对象的方式处理数据。
  4. 整合服务熔断和限流:Feign与Spring Cloud的熔断器(如Hystrix)和限流器(如Sentinel)集成,可以提供服务熔断和限流的能力,增加系统的稳定性和可靠性。
  5. 易于扩展:Feign提供了可插拔的机制,允许您通过自定义配置和拦截器等方式来扩展和定制其行为。

 二、Feign的使用

这里我以 pig 项目为例进行说明。项目地址:https://gitee.com/log4j/pig

1. 项目模块说明

pig
├── pig-auth -- 授权服务提供[3000]
└── pig-common -- 系统公共模块
     ├── pig-common-bom -- 全局依赖管理控制
     ├── pig-common-core -- 公共工具类核心包
     ├── pig-common-datasource -- 动态数据源包
     ├── pig-common-job -- xxl-job 封装
     ├── pig-common-log -- 日志服务
     ├── pig-common-mybatis -- mybatis 扩展封装
     ├── pig-common-seata -- 分布式事务
     ├── pig-common-security -- 安全工具类
     ├── pig-common-swagger -- 接口文档
     ├── pig-common-feign -- feign 扩展封装
     └── pig-common-xss -- xss 安全封装
├── pig-register -- Nacos Server[8848]
├── pig-gateway -- Spring Cloud Gateway网关[9999]
└── pig-upms -- 通用用户权限管理模块
     └── pig-upms-api -- 通用用户权限管理系统公共api模块
     └── pig-upms-biz -- 通用用户权限管理系统业务处理模块[4000]
└── pig-visual
     └── pig-monitor -- 服务监控 [5001]
     ├── pig-codegen -- 图形化代码生成 [5002]
     ├── pig-sentinel-dashboard -- 流量高可用 [5003]
     └── pig-xxl-job-admin -- 分布式定时任务管理台 [5004]

 2. Feign客户端定义

(1)引入Feign依赖

在pig-upms-api模块和pig-upms-biz模块都需要引入feign依赖:

        <!--feign 注解依赖-->
        <dependency>
            <groupId>com.pig4cloud</groupId>
            <artifactId>pig-common-feign</artifactId>
            <optional>true</optional>
        </dependency>

(2)定义位置

        在代码中可以看到,Feign的客户端定义在了 pig-upms-api 模块中。将Feign的客户端定义在pig-upms-api模块下是一种常见的设计模式。这种模式的目的是将Feign的客户端接口定义为API模块的一部分,使得其他模块可以通过引入pig-upms-api依赖来使用该API,并通过Feign实现与pig-upms-biz模块(通用用户权限管理系统的业务处理模块)之间的通信。

 (3)Feign客户端定义

RemoteUserService为例:

//标识这是一个Feign客户端接口,contextId指定客户端的id,用于和其他客户端区分
//value="pig-upms-biz" 指定了要调用的服务名称
@FeignClient(contextId = "remoteUserService", value = ServiceNameConstants.UMPS_SERVICE)
public interface RemoteUserService {


	//通过用户名查询用户、角色信息

	//@GetMapping注解指定了要调用的HTTP GET请求的路径。这里是 /user/info/{username}
	//headers指定了请求的头部信息,这里HEADER_FROM_IN的值是"from=Y"
	@GetMapping(value = "/user/info/{username}", headers = SecurityConstants.HEADER_FROM_IN)
	R<UserInfo> info(@PathVariable("username") String username);

	//通过手机号码查询用户、角色信息
	@GetMapping(value = "/app/info/{phone}", headers = SecurityConstants.HEADER_FROM_IN)
	R<UserInfo> infoByMobile(@PathVariable("phone") String phone);
	
	//根据部门id,查询对应的用户 id 集合
	@GetMapping(value = "/user/ids", headers = SecurityConstants.HEADER_FROM_IN)
	R<List<Long>> listUserIdByDeptIds(@RequestParam("deptIds") Set<Long> deptIds);

}

实际上这个Feign客户端会发送请求到SysUserController

 (4)在其他模块测试

比如说,我想要在 pig-codegen 模块下使用 Feign 进行接口调用,需要先在 codegen 模块引入 pig-upms-api 的依赖,因为我们将Feign的客户端定义在了pig-upms-api下。

        <!--upms api、model 模块-->
        <dependency>
            <groupId>com.pig4cloud</groupId>
            <artifactId>pig-upms-api</artifactId>
        </dependency>

编写一个测试Controller:

@RestController
@RequiredArgsConstructor  //自动生成构造方法,在生成FeignDemoController会将remoteUserService传入
@RequestMapping("/feignDemo")
public class FeignDemoController {

	//注入Feign客户端接口 RemoteUserService
	//定义为final 确保在实例化后变量不会发生意外改变
	private final RemoteUserService remoteUserService;

	@Inner(value = false)
	@GetMapping("/test")
	public R<UserInfo> test() {
		//假设传入的用户名是 admin
		String username = "admin";
		//调用feign中的info方法
		return remoteUserService.info(username);
	}
}

启动服务测试,可以看到成功获取到了admin用户的信息:

补充:关于在两种注入方式的理解:

在注入remoteUserService属性时,可以使用@RequiredArgsConstructor注解或@Autowired注解两种方式。这两种方式有以下区别:

  1. @RequiredArgsConstructor: 当在类上使用@RequiredArgsConstructor注解时,它会自动为您生成一个构造方法,该构造方法会将remoteUserService作为参数传入并进行注入。这种方式是通过构造函数注入依赖。使用@RequiredArgsConstructor注解可以简化代码,减少手动编写构造方法的工作。

  2. @Autowired: 当在属性上使用@Autowired注解时,它会自动将相应类型的实例注入到该属性中。这种方式是通过字段注入依赖。Spring框架会自动扫描并查找与RemoteUserService类型匹配的实例,并将其注入到remoteUserService属性中。使用@Autowired注解可以方便地进行依赖注入,但需要确保所需的实例存在且唯一。

总体而言,这两种注入方式的效果是一样的,都会将RemoteUserService注入到remoteUserService属性中。选择使用哪种方式取决于偏好和项目中的约定。使用@RequiredArgsConstructor可以提供更简洁的代码,而使用@Autowired则更加灵活,可以适应更多不同的场景。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

EmEditor自定义快捷键之下一个标签页上一个标签页

EmEditor自定义快捷键 有好几种叫法 下一个标签页上一个标签页 下一个选项卡上一个选项卡 在这里个软件它叫’右侧文档’ ‘左侧文档’ 工具 - 所有配置的属性 - 键盘 - 窗口 - 类别: 选’窗口’ - 依次选 ‘右边的文档’ ‘左边的文档’ 按下新的快捷键 - 是每次只按一个键(不…

简单的复习下与 CSS Flex 布局相关的几个关键属性

揭开align-content、justify-content、align-items和justify-items的神秘面纱&#xff0c;解释它们各自的功能以及在不同的情境下如何使用。 在过去几年中&#xff0c;由于弹性盒子和网格布局的演变&#xff0c;CSS布局设计的艺术发生了重大变化。而这一变革的核心&#xff0c;…

CS231N assignment3 RNN

对作业进行一些形象的解释 首先是def rnn_step_forward&#xff1a; 这里的t时刻其实就是一个句子里面的单词数&#xff0c;为了方便会统一到一个最长长度&#xff0c;对于比这个长度短的部分用null进行填充&#xff0c;并且在方法内部会让Null不进行传播和梯度计算。 我们最…

AIGC的发展史:从模仿到创造,AI的创造性探索

在 AI时代&#xff0c;人工智能不再是简单的机器&#xff0c;而是一个具有无限创造力的创造者。AIGC的诞生是人工智能从模仿到创造的一种进步&#xff0c;也是对人类创造力的一种新探索。 而这种由AI生成的内容究竟是如何发展而来的呢&#xff1f;在本文中&#xff0c;我们将探…

QT检测USB HID设备的拔插

网上的参考代码很多&#xff0c;比如下面这个&#xff1a; QT 检测hid设备拔插打印设备信息_qt hid打印机_研知电子的博客-CSDN博客 但是&#xff0c;参考了很多人的代码&#xff0c;写出来的发现检测不到USB HID设备的拔插。 明明其他人都可以正常使用&#xff0c;那问题应…

java内存区 || 并发

目录 什么是线程&#xff1f; 线程的创建和上下文切换&#xff1a; 线程的入栈和出栈&#xff1a; 堆栈的作用&#xff1a; CPU核心数概念 线程的start状态 就绪队列 操作系统的时间片 线程中代码执行顺序 实际中内存图 什么是线程&#xff1f; 线程的创建和上下文切换…

【android12】给第三方应用APK添加系统签名

一、背景 自己或者客户的第三方apk需要用到很多系统权限&#xff0c;所以要内置到系统目录下&#xff0c;变成系统自带的APP&#xff0c;如果不用系统文件生成的签名安装&#xff0c;会导致APP远程更新失败提示签名错误。 二、环境准备 1.Ubuntu系统&#xff08;推荐1804版本及…

Invalid name=“org.apache.dubbo.config.ApplicationConfig#0“

上一篇文章是springboot 集成 dubbo&#xff1a; spring boot 集成dubbo_Demonor_的博客-CSDN博客 在集成的时候出现了一些异常&#xff0c;在这里记录一下&#xff0c;并排查出原因 异常信息1&#xff1a; [2m2023-07-11 20:38:39.387[0;39m [32m INFO[0;39m [35m21492[0;…

92.qt qml-日期/日期时间/时间选择器(日历选择器)

截图如下所示: 效果图如下所示: 1.前言 QML日历组件我们之前移植过: 67.qt quick-qml自定义日历组件(支持竖屏和横屏)_qml日历_诺谦的博客-CSDN博客 但是该组件内部代码比较坑的就是全部使用自定义对象,导致性能不行,动画卡顿,并且不好加时间选择,所以本章我们重新学…

Mysql 实现批量插入对已存在数据忽略或更新

Mysql 实现批量插入对已存在数据忽略/更新 文章目录 Mysql 实现批量插入对已存在数据忽略/更新一. 表的准备二. 实现2.1 实现原理2.2 批量插入对已存在数据忽略 一. 表的准备 CREATE TABLE demo (id int NOT NULL AUTO_INCREMENT COMMENT 主键id,name varchar(10) DEFAULT NUL…

重磅IntelliJ IDEA 2023.2 新版本即将发布,拥抱 AI

IntelliJ IDEA 近期连续发布多个EAP版本&#xff0c;官方在对用户体验不断优化的同时&#xff0c;也新增了一些不错的功能&#xff0c;尤其是人工智能助手补充&#xff0c;AI Assistant&#xff0c;相信在后续IDEA使用中&#xff0c;会对开发者工作效率带来不错的提升。 以下是…

基于A*的二维多无人机航线规划

Matlab航迹规划仿真——A*算法_航迹起始算法 matlab_致守的博客-CSDN博客 matlab2016及以上可以运行 astar.m function [] astar(Spoint,Epoint,Matrix,m,n,h1,h2) %%寻路 Matrix(Spoint(1),Spoint(2))0; Matrix(Epoint(1),Epoint(2))inf; GMatrix; FMatrix; openlistMatri…

安全防御 --- DDOS攻击(01)

DOS攻击&#xff08;deny of service&#xff09;--- 拒绝式服务攻击 例&#xff1a;2016年10月21日&#xff0c;美国提供动态DNS服务的DynDNS遭到DDOS攻击&#xff0c;攻击导致许多使用DynDNS服务的网站遭遇访问问题&#xff0c;此事件中&#xff0c;黑客人就是运用了DNS洪水…

ceph--RBD的使用

Ceph-RDB 1、RBD架构图 Ceph 可以同时提供对象存储 RADOSGW、块存储 RBD、文件系统存储 Ceph FS,RBD 即 RADOS Block Device 的简称&#xff0c;RBD 块存储是常用的存储类型之一&#xff0c;RBD 块设备类似磁盘 可以被挂载&#xff0c;RBD 块设备具有快照、多副本、克隆和一致…

今天实习第一天,用git

老板问了我是否用过gitee&#xff0c;并且是否用过git&#xff0c;在集成工具中&#xff0c;会git来提交代码。我说没有。 所以&#xff0c;先使用gitee。 01.登录gitee的官网&#xff0c;在此处登录。 02.绑定邮箱&#xff0c;我用的是QQ邮箱。

服务端研发提测模板

test环境分支自测通过 提测邮件标注test环境分支 【xxxxxx需求】服务端研发提测了&#xff0c;快去测试吧!

vue3中的provide

作用:实现祖孙件通信套路:父组件有一个provide选项来提供数据,子组件有一个inject选项来开始使用这些数据具体写法: 祖组件中: <template><div class"lim"><h2>祖组件</h2><child></child>名字:{{ car.name }}<br>价格:…

SpringBoot与Vue前后端分离项目。用Nginx代理。

Nginx代理主要是解决跨域与负载均衡的作用。 我这里用的自己的电脑&#xff0c;用的windows系统&#xff0c;不过配置基本是和Linux一样的。 下载Nginx nginx: download Nginx常用命令&#xff0c;先cd到解文件夹路径&#xff1a; nginx.exe&#xff1a;开启服务。nginx -s…

预训练模型相关整理

1、怎么使用预训练网络&#xff1f; 使用预训练网络有两种方法&#xff1a;特征提取&#xff08;feature extraction&#xff09;和微调模型&#xff08;fine-tuning&#xff09;。 1、特征提取 特征提取是使用之前网络学到的表示来从新样本中提取出有趣的特征。然后将这些特…

深入理解Linux网络——内核是如何发送网络包的

文章目录 一、相关实际问题二、网络包发送过程总览三、网卡启动准备四、数据从用户进程到网卡的详细过程1&#xff09;系统调用实现2&#xff09;传输层处理1. 传输层拷贝2. 传输层发送 3&#xff09;网络层发送处理4&#xff09;邻居子系统5&#xff09;网络设备子系统6&#…