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

声明式微服务通信新范式:OpenFeign如何简化RestTemplate调用

一、OpenFeign介绍

        OpenFeign 是一个声明式 Web Service 客户端框架,它极大地简化了微服务之间的调用过程。通过 OpenFeign,开发者可以像在 Controller 中调用 Service 一样轻松实现服务间通信 - 只需定义接口并添加相应注解即可完成远程调用

Spring Cloud FeignSpring 对 Feign 的封装实现,将其集成到 Spring Cloud 生态系统中

Feign 项目更名影响,Spring Cloud Feign 提供两个 starter 包:

  • spring-cloud-starter-feign
  • spring-cloud-starter-openfeign

鉴于 Feign 已停止维护,推荐使用 spring-cloud-starter-openfeign 作为项目依赖

Spring cloud OpenFeign 官方文档https://spring.io/projects/spring-cloud-openfeign/

二、简单演示

        我们将通过OpenFeign框架逐步修改订单服务中调用商品服务的代码逻辑,以下针对订单服务进行更改

2.1、添加依赖

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2.2、添加注解

        在order-service的启动类中添加@EnableFeignClients注解,以启用OpenFeign功能

@EnableFeignClients
@SpringBootApplication
public class OrderServiceApplication {public static void main(String[] args) {SpringApplication.run(OrderServiceApplication.class, args);}
}

2.3、编写客户端

        定义一个新增接口,用于声明获取商品信息的方法(该方法与订单服务Controller层功能一致,即通过注册中心远程调用商品服务Controller中的商品信息获取方法)

@FeignClient(value = "product-service",path = "/product")
public interface ProductApi {@RequestMapping("/{id}")ProductInfo getProductInfo(@PathVariable("id") Integer productId);
}

@FeignClient 注解用于声明式 REST 客户端接口,主要参数说明:

        value/name​​:指定目标微服务的名称(与服务注册中心中注册的服务名一致),用于服务发现。Feign 会通过服务名从注册中心获取服务实例列表,并默认通过 ​​Spring Cloud LoadBalancer​​ 实现负载均衡(若未显式配置其他负载均衡器)。若需直接访问固定地址(不经过服务发现),可通过 url 属性指定具体 URL

        ​​path​​:为当前 Feign 接口配置统一的请求路径前缀。接口中方法的路径会与该前缀拼接,形成完整的请求路径。例如示例中 path = "/product",方法  @RequestMapping(" / { id } ") 的完整路径为 /product/ { id }

2.4、远程调用

        在订单服务的Service层修改远程调用代码:注入ProductApi对象,进行远程调用,即可避免手动拼接URL,减少可能发生的拼接错误

@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate ProductApi productApi;public OrderInfo selectOrderById(Integer orderId) {OrderInfo orderInfo = orderMapper.selectOrderById(orderId);ProductInfo productInfo=productApi.getProductInfo(orderInfo.getProductId());
//        代码注释为源代码
//        String url="http://product-service/product/"+orderInfo.getProductId();
//        ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);orderInfo.setProductInfo(productInfo);return orderInfo;}
}

2.5、测试

        启动服务后并观察Nacos

        访问 127.0.0.1:8080/order/1 ,可发现通过OpenFeign远程调用成功

三、OpenFeign的参数传递

3.1、传递单个参数

         先在服务端定义相应的接口,在商品服务的Controller层中,增加一个获取参数功能        

    @RequestMapping("/p1")public String p1(Integer id){return "接收到参数,id"+id;}

        Feign的客户端进行声明 p1 方法

@FeignClient(value = "product-service",path = "/product")
public interface ProductApi {@RequestMapping("/{id}")ProductInfo getProductInfo(@PathVariable("id") Integer productId);@RequestMapping("p1")String p1(@RequestParam("id") Integer id);
}

        客户端通过Feign发起远程调用

@RestController
@RequestMapping("/feign")
public class FeignController {@Autowiredprivate ProductApi productApi;@RequestMapping("/o1")public String o1(Integer id){return productApi.p1(id);}
}

        当前代码调用关系为:客户端 o1 ——> Feign的 p1 ——> 服务端的 p1,访问:127.0.0.1:8080/feign/o1?id=3  观察结果:

3.2、传递多个参数

        步骤与传递单个参数类似:先在服务端定义相应的接口,然后Feign客户端声明 p2 方法,再进行远程调用,代码如下

    @RequestMapping("/p2")public String p2(Integer age,String name){return "今年 "+name+" 刚满 "+age;}
    @RequestMapping("/p2")String p2(@RequestParam("age") Integer age,@RequestParam("name") String name);
    @RequestMapping("/o2")public String o2(Integer age,String name){return productApi.p2(age,name);}

        最后重启服务,访问: 127.0.0.1:8080/feign/o2?age=18&name=“小美” 观察结果:

3.3、传递对象

    //服务端定义一个接口@RequestMapping("/p3")public String p3(ProductInfo productInfo){return "传递对象:"+productInfo.toString();}//Feign客户端声明该方法@RequestMapping("/p3")String p3(@SpringQueryMap ProductInfo productInfo);//进行远程调用@RequestMapping("/o3")public String o3(){ProductInfo productInfo=new ProductInfo();productInfo.setId(222);productInfo.setProductName("卡塞尔学院校服");return productApi.p3(productInfo);}

        访问相应链接,观察结果:

3.4、传递JSON

    //服务端定义一个接口@RequestMapping("/p4")public String p4(@RequestBody ProductInfo productInfo){return "传递JSON:"+productInfo.toString();}//Feign客户端声明该方法@RequestMapping("/p4")String p4(@RequestBody ProductInfo productInfo);//进行远程调用@RequestMapping("/o4")public String o4(){ProductInfo productInfo=new ProductInfo();productInfo.setId(333);productInfo.setProductName("白色连衣裙");return productApi.p4(productInfo);}

        访问相应链接,观察结果:

http://www.dtcms.com/a/352275.html

相关文章:

  • Windows下实现类似`watch nvidia-smi`的实时监控效果
  • 进入docker中mysql容器的方法
  • Java:TreeSet的使用
  • (Arxiv-2024)VideoMaker:零样本定制化视频生成,依托于视频扩散模型的内在力量
  • QT qml(quick3D)模型的移动
  • 专业解读《Light》封面:可调谐混合超表面(THCMs)如何革新下一代LiDAR系统
  • 3D游戏角色建模资源搜索指南(资料来源于网络)
  • 湖仓一体:小米集团基于 Apache Doris + Apache Paimon 实现 6 倍性能飞跃
  • JavaWeb之分布式事务规范
  • LInux(二十一)——Linux SSH 基于密钥交换的自动登录原理简介及配置说明
  • jenkins2025配置邮箱发送
  • 基于Android的车位预售预租APP/基于Android的车位租赁系统APP/基于Android的车位管理系统APP
  • Leetcode—1163. 按字典序排在最后的子串【困难】
  • Linux(二十二)——服务器初始化指南
  • cuda编程笔记(16)--使用 cuDNN 实现卷积、激活、池化等反向操作
  • 刀客doc:沃尔玛取消与TTD的独家合作,对程序化广告意味着什么?
  • 【RAGFlow代码详解-23】聊天系统架构
  • 字节跳动国际版 TRAE 深度解析:重新定义 AI 时代的编程体验
  • Docker化性能监控平台搭建:JMeter+InfluxDB+Grafana全攻略
  • Vite 模块联邦插件 实现微前端架构,其核心原理概述
  • 网络安全零基础入门:2025核心知识与系统学习路径分享
  • 工地考勤数据、监控回传与远程办公需求,如何通过贝锐蒲公英实现?
  • 做项目总是出问题,如何提升项目管理能力?
  • (MySQL索引事务) 本节目标 索引 事务
  • JUC之并发编程总结
  • 控制系统仿真之基础知识(一)
  • Nat Commun|“铃铛病”的空间多组学揭示基质细胞在疾病发生中的核心地位
  • 广告推荐模型1:逻辑回归(Logistic Regression,LR)
  • WebSocket实时通信系统——js技能提升
  • Linux 详谈软硬链接