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

SpringCloud Feign 声明式服务调用

一、Feign 是什么?

Feign 是 Spring Cloud 提供的一个声明式 HTTP 客户端,用来简化微服务之间的远程调用。

  • 你只需要写一个接口,加几个注解,就能像调用本地方法一样调用远程服务
  • 它内部已经集成了 Ribbon,自带负载均衡能力

核心优势

代码极度简洁:不用手动拼接 URL、不用自己写 HTTP 请求

自带负载均衡:和 Ribbon 无缝集成,支持轮询、随机等策略

支持 Spring MVC 注解:@RequestMapping@RequestParam@PathVariable等都能用

Feign 与 Ribbon / 负载均衡的关系

Feign 内部默认集成了 Ribbon,自带负载均衡能力

你不需要手动给 RestTemplate 加@LoadBalanced,Feign 已经帮你做好了

默认负载均衡策略是轮询,也可以自定义策略:

二,使用feign

创建文件 四个工程

创建接口

feign_consumer

在启动类 添加 EnableFeignClients 注解 扫描 Feign的注解 @FeignClient("feign-provider")


@Autowired
private UserFeign userFeign; 只需要这一个就行

在启动

在访问 consumer的 路径就会跳转 common1和common2 的内容了

三,feign的原理


1、@EnableFeignClients开启feign注解的支持:FeignClientsRegistrar.registerFeignClients():扫描被@FeignClient标识的接口并生成代理类交给spring容器管理
2、为接口方法创建requestTemplate:当consumer调用feign的代理类时,代理类会调用SynchronousMethodHandler.invoke()创建requestTemplate

四、feign的传参方式

1、?传参
@RequestParam("sb"):url?sb=250
2、restful传参
@PathVariable("sb"):url/{sb}--->url/250
3、pojo传参
@RequestBody:pojo--->json

feign_consumer

package com.yunkukukukuku.controller; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/consumer") public class ConsumerController { @Autowired private UserFeign userFeign; // Feign 客户端 //获取用户信息 {} 传参 @RequestMapping("/getUserById/{id}") public User getUserById(@PathVariable Integer id) { // 调用 Feign 客户端的方法获取用户信息 return userFeign.getUserById(id); } //restful 传参 @RequestMapping("/getUserById2") public User getUserById2( User user) { return userFeign.getUserById2(user); } //? 传参 @RequestMapping("/getUserById3") public User getUserById3(@RequestParam("id") Integer id) { // 调用 Feign 客户端的方法获取用户信息 return userFeign.getUserById3(id); } //pojo 传参 @RequestMapping("/getUserById4") public List<User> getUserById4() { List<User> userList = new ArrayList<>(); ----- return userFeign.getUserById4(userList); } }

feign_interface

package com.yunkukukukuku; import java.util.List; @FeignClient("feign-provider") @RequestMapping("/provider") public interface UserFeign { //获取用户信息 {} 传参 @RequestMapping("/getUserById/{id}") public User getUserById(@PathVariable("id") Integer id);//PathVariable 获取路径中的参数 //restful @RequestMapping("/getUserById2") User getUserById2( @RequestBody User user);//RequestBody 获取请求体中的参数 //? 传参 @RequestMapping("/getUserById3") User getUserById3(@RequestParam("id") Integer id);//RequestParam 获取路径中的参数 //pojo 传参 @RequestMapping("/getUserById4") List<User> getUserById4(List<User> userList); }

feign_provider_1 controller

package com.yunkukukukuku.controller; import java.util.List; @RestController @RequestMapping("/provider") public class ProviderController { @Autowired private UserService userService; @RequestMapping("/getUserById/{id}") public User getUserById(@PathVariable Integer id) { return userService.getUserById(id); } //restful @RequestMapping("/getUserById2") public User getUserById2(@RequestBody User user) { return userService.getUserById2(user); } //? 传参 @RequestMapping("/getUserById3") User getUserById3(@RequestParam("id") Integer id) { return userService.getUserById3(id); } //pojo 传参 @RequestMapping("/getUserById4") public List<User> getUserById4(List<User> userList) { return userService.getUserById4(userList); } }

五,补充

坑 1:对象参数传参报错(你之前的 IllegalStateException)

  • 问题:Feign 默认会把对象参数当成@RequestBody处理,而你的 Provider 端是用 URL 查询参数接收

  • 解决:Feign 接口的对象参数上必须加@SpringQueryMap,让它自动把对象展开成?id=12&name=xxx格式的 URL 参数

坑 2:@PathVariable不加参数名报错

  • 问题:Feign 接口中@PathVariable("id")必须指定参数名,否则无法绑定路径变量

  • 解决:必须写@PathVariable("id"),不能省略"id"

坑 3:@RequestParam必须指定参数名

  • 问题:Feign 接口中@RequestParam("id")必须指定参数名,否则会报错

  • 解决:必须写@RequestParam("id"),不能省略"id"

场景注解适用请求方式备注
路径变量@PathVariableGET路径中必须有{变量名}
URL 查询参数(单个)@RequestParamGET/POST必须指定参数名
URL 查询参数(对象)@SpringQueryMapGET/POST必须加此注解
请求体 JSON@RequestBodyPOST/PUT只能用 POST/PUT,不能用 GET
http://www.jsqmd.com/news/658260/

相关文章:

  • 易语言YOLO全版本模块包重磅升级:支持YOLOv10,一键部署免配置
  • C语言随机数生成技巧
  • **脑机接口编程新范式:用Python与OpenBCI构建实时神经信号处理系统**在人工智能与人
  • 好用的东莞高新技术企业认定哪个公司好
  • 别再只盯着激光雷达了!聊聊低成本单目摄像头测距在机器人/小车项目里的那些事儿
  • mysql如何导出特定条件的查询数据_使用mysqldump加where参数
  • Python自动化数据可视化报告:用代码一键生成专业的分析报表
  • Cgo回调函数中处理 const char- 类型参数的正确方法
  • 别再写if-elseif-else了!Matlab里这5个坑,新手程序员踩过几个?
  • 智能代码生成落地困局(长代码稳定性白皮书·2024内部版)
  • 概率论核心概念与应用场景全解析(建议收藏)
  • 实践指南-OpenSSL中AES的ECB模式:从原理到安全编程实现
  • AI 时代工程师 Superpowers 进化论:从写代码到调模型,核心能力如何升维重构
  • AI文档生成工具实战白皮书(SITS2026 2024年度权威测评版)
  • CN3153 安培锂电池充电管理集成电路
  • 使用BERTopic对名言数据集进行批量主题建模的完整实践指南
  • 生成式AI ROI迟迟不显?SITS2026实测验证的4个可量化增效杠杆与21天见效路径图
  • CefFlashBrowser完整指南:在2025年完美运行Flash内容的终极解决方案
  • Airtable 与 NocoBase:从Excel迁移的真实成本对比
  • YOLOv11的yaml配置文件里,C3k2和C2PSA模块到底怎么用?手把手教你调参
  • 大模型、Agent、Skill与OpenClaw如何重塑智能体验?
  • 利用Qwen3进行软件测试用例可视化生成与评审
  • 安装宝塔面板提示权限不足_使用root用户进行规范安装
  • 如何3分钟搞定网易云音乐NCM文件转换:ncmdumpGUI完整指南
  • Java 安全最佳实践 2027:构建安全可靠的应用
  • PHP怎么实现Yii2 ActiveRecord_Yii2数据库ORM模型【操作】
  • yz-bijini-cosplay新手入门:无需重复加载底座,LoRA动态切换快速体验
  • 智能代码生成错误检测与修复(工业级误报率<0.8%的闭环系统大公开)
  • 基于内存补丁技术的企业级消息防撤回完全手册
  • 2025必备!5款免费AI论文检测工具实测,低查重高原创一站搞定