Openfeign的最佳实践

news2025/4/19 14:29:29

文章目录

  • 问题引入
  • 一、继承的方式
    • 1. 建立独立的Moudle服务
    • 2. 服务调用方继承jar包中的接口
    • 3. 直接注入继承后的接口进行使用
  • 二、抽取的方式
    • 1. 建立独立的Moudle服务
    • 2.服务调用方依赖注入

问题引入

openfeign接口的实现和服务提供方的controller非常相似,例如:

  • 服务端
@RequestMapping("/product")
public class ProductController implements ProductInterface {

    @Autowired
    private ProductService productService;

    @RequestMapping("/{productId}")
    public ProductInfo getProductInfoById(@PathVariable("productId") Integer productId){
        log.error("开始运行product-service");
        return productService.selectProductById(productId);
    }

    @RequestMapping("/p1")
    public String p1(Integer id){
        return "product-service  "+id;
    }

    @RequestMapping("/p2")
    public String p2(Integer id,String name){
        return id+" "+name;
    }

    @RequestMapping("/p3")
    public String p3(ProductInfo productInfo){
        return productInfo.toString();
    }

    //返回json格式
    @RequestMapping("/p4")
    public String p4(@RequestBody ProductInfo productInfo){
        return productInfo.toString();
    }
}

  • openfeign接口
@RequestMapping("/feign")
@RestController
public class FeignController {

    @Autowired
    private ProductApi productApi;

    //@RequestParam不可以省略
    @RequestMapping("/o1")
    public String o1(Integer id){
        return productApi.p1(id);
    }

    //@RequestParam不可以省略
    @RequestMapping("/o2")
    public String o2(Integer id,String name){
        return productApi.p2(id,name);
    }

    @RequestMapping("/o3")
    public String o3(){
        ProductInfo productInfo = new ProductInfo();

// 使用 setter 方法设置字段
        productInfo.setId(101);
        productInfo.setProductName("华为Mate60");
        productInfo.setProductPrice(6999);
        productInfo.setState(1);

        return productApi.p3(productInfo);
    }


    @RequestMapping("/o4")
    public String o4(){
        ProductInfo productInfo = new ProductInfo();

// 使用 setter 方法设置字段
        productInfo.setId(101);
        productInfo.setProductName("华为Mate60");
        productInfo.setProductPrice(6999);
        productInfo.setState(1);
        return productApi.p4(productInfo);
    }
}

如果有多个服务调用方,我们就需要写多次这种重复的代码,比较麻烦。
那么我们希望能不能有一个简介的写法去实现呢?

答案是有的,主要有两种方式:

  • 继承的方式
  • 抽取的方式

一、继承的方式

1. 建立独立的Moudle服务

在这里插入图片描述

注意:product-api也是一个独立的服务,所以也需要引入spring-boot和spring-cloud-openfeign相关依赖。

把Openfeign接口的方法统一放到product-api中:


public interface  ProductInterface {
    @RequestMapping("/{productId}")
    ProductInfo getProductInfoById(@PathVariable("productId") Integer productId);

    //@RequestParam不可以省略
    @RequestMapping("/p1")
    String p1(@RequestParam("id") Integer id);


    @RequestMapping("/p2")
    String p2(@RequestParam("id") Integer id,@RequestParam("name") String name);

    //@SpringQueryMap把传过来的Java对象的字段转换成url格式
    @RequestMapping("/p3")
    String p3(@SpringQueryMap ProductInfo productInfo);

    //返回json格式
    @RequestMapping("/p4")
    String p4(@RequestBody ProductInfo productInfo);
}

这些接口的方法中可能涉及别的服务的实体类,因此我们需要导入其他服务中的实体类。

创建好这个服务后,对这个服务进行打成jar包:

在这里插入图片描述

2. 服务调用方继承jar包中的接口

@FeignClient(value = "product-service",path="/product")//指定需要访问的服务的名称 application-name
public interface ProductApi extends ProductInterface {
}

注意需要导入刚才打好的jar包依赖:

       <dependency>
            <groupId>com.hyy</groupId>
            <artifactId>product-api</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>

3. 直接注入继承后的接口进行使用

public class FeignController {

    @Autowired
    private ProductApi productApi;

    //@RequestParam不可以省略
    @RequestMapping("/o1")
    public String o1(Integer id){
        return productApi.p1(id);
    }
}

这就是继承的方式实现openfeign,我们不需要对每一个服务调用方写方法的实现了,简化了编写流程,这种继承的方式是spring官方推荐的。

二、抽取的方式

抽取的方式,把解耦合做的更彻底,把opnfeign远程远程调用的功能全部统一放到一个服务中,其他服务调用方使用它提供的jar包即可,相比于继承的方式,抽取的方式连继承都不用写,直接依赖注入即可。

1. 建立独立的Moudle服务

在这里插入图片描述

同样地,这里的product-api也是一个独立的服务,所以也需要引入spring-boot和spring-cloud-openfeign相关依赖。

把Openfeign接口的方法统一放到product-api中:


//因为解耦合彻底,这里把远程调用涉及的指定服务也需要加上,避免在服务调用方重新配置
@FeignClient(value = "product-service",path="/product")//指定需要访问的服务的名称 application-name
public interface  ProductInterface {
    @RequestMapping("/{productId}")
    ProductInfo getProductInfoById(@PathVariable("productId") Integer productId);

    //@RequestParam不可以省略
    @RequestMapping("/p1")
    String p1(@RequestParam("id") Integer id);


    @RequestMapping("/p2")
    String p2(@RequestParam("id") Integer id,@RequestParam("name") String name);

    //@SpringQueryMap把传过来的Java对象的字段转换成url格式
    @RequestMapping("/p3")
    String p3(@SpringQueryMap ProductInfo productInfo);

    //返回json格式
    @RequestMapping("/p4")
    String p4(@RequestBody ProductInfo productInfo);
}

同样地,某些其他服务的实体类也需要我们导入,比如ProductInfo等。
值得注意的是:
如果服务调用方的实体类与openfeign接口的实体类路径不同,我们需要统一使用openfeign接口的实体类地址

创建好这个服务后,对这个服务进行打成jar包:

在这里插入图片描述

2.服务调用方依赖注入


//下面是spring mvc的程序
@RequestMapping("/feign")
@RestController
public class FeignController {

//注入刚才打好的jar包(注意也需要导入jar包依赖)
    @Autowired
    private ProductApi productApi;

//依赖注入完之后,就可以直接使用远程调用了
    //@RequestParam不可以省略
    @RequestMapping("/o1")
    public String o1(Integer id){
        return productApi.p1(id);
    }

 

个人认为抽取的方式会跟加好用,因为它解耦合更彻底,完全可以看作是一个独立的模块,尽管继承的方式是官方推荐的。

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

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

相关文章

Buildroot编译过程中下载源码失败

RK3588编译一下recovery&#xff0c;需要把buildroot源码编译一遍。遇到好几个文件都下载失败&#xff0c;如下所示 pm-utils 1.4.1这个包下载失败&#xff0c;下载地址http://pm-utils.freedesktop.org/releases 解决办法&#xff0c;换个网络用windows浏览器下载后&#xff…

OpenCV 图形API(43)颜色空间转换-----将 BGR 图像转换为 LUV 色彩空间函数BGR2LUV()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 将图像从BGR色彩空间转换为LUV色彩空间。 该函数将输入图像从BGR色彩空间转换为LUV。B、G和R通道值的传统范围是0到255。 输出图像必须是8位无符…

自问自答模式(Operation是什么)

自问自答 问&#xff1a;Operation 注解来自哪里&#xff1f; 答&#xff1a;Operation 是 OpenAPI&#xff08;Swagger&#xff09;规范中&#xff0c;来自 io.swagger.v3.oas.annotations 包的一个注解&#xff0c;用于给 REST 接口增加文档元数据。 问&#xff1a;summary …

996引擎-实战笔记:Lua 的 NPC 面板获取 Input 内容

996引擎-实战笔记:Lua 的 NPC 面板获取 Input 内容 获取 Input 内容测试NPC参考资料获取 Input 内容 测试NPC -- NPC入口函数 function main(player)local msg = [[<Img|id=9527|x=0|y=0|width=300|height=150|img=public/bg_npc_01.png|bg=1|move=1|reset=1|show=0|layer…

少数服从多数悖论、黑白颠倒与众人孤立现象之如何应对(一)

观己之前&#xff0c;也可先观众生 如果当时没有袖手旁观&#xff0c;或许唇不亡齿也不会寒 ■如何轻松/更好应对个别被众人孤立&#xff08;他人、辨别、自己&#xff09; ●他人被孤立 不参与 有余力&#xff0c;助弱者 被孤立者本身有问题 •不参与&#xff1a;不会辨…

leetcode0058. 最后一个单词的长度-easy

1 题目&#xff1a;最后一个单词的长度 官方标定难度&#xff1a;易 给你一个字符串 s&#xff0c;由若干单词组成&#xff0c;单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。 单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。 示例 1&#x…

新一代电子海图S-100标准

随着航海技术的不断发展&#xff0c;国际海事组织&#xff08;IMO&#xff09;和国际航道测量组织&#xff08;IHO&#xff09;不断推动电子海图标准的更新&#xff0c;以提高航行安全和效率。S-100标准作为新一代电子海图标准&#xff0c;为电子海图显示和信息系统&#xff08…

力扣热题100——普通数组(不普通)

普通数组但一点不普通&#xff01; 最大子数组和合并区间轮转数组除自身以外数组的乘积缺失的第一个正数 最大子数组和 这道题是非常经典的适用动态规划解决题目&#xff0c;但同时这里给出两种解法 动态规划、分治法 那么动态规划方法大家可以在我的另外一篇博客总结中看到&am…

深度学习与机器学习的关系解析:从基础到应用

&#x1f4cc; 友情提示&#xff1a; 本文内容由银河易创AI&#xff08;https://ai.eaigx.com&#xff09;创作平台的gpt-4-turbo模型生成&#xff0c;旨在提供技术参考与灵感启发。文中观点或代码示例需结合实际情况验证&#xff0c;建议读者通过官方文档或实践进一步确认其准…

工业物联网的可视化编程革新:Node-RED与边缘计算的深度融合-纵横智控

在工业物联网的演进历程中&#xff0c;可视化编程工具正成为打破技术壁垒的核心力量。Node-RED作为开源的可视化编程平台&#xff0c;通过其独特的拖拽式逻辑构建能力&#xff0c;为设备连接、数据处理与业务逻辑设计提供了全新范式。本文将深入解析Node-RED的技术优势&#xf…

深度学习 从入门到精通 day_02

1. 自动微分 自动微分模块torch.autograd负责自动计算张量操作的梯度&#xff0c;具有自动求导功能。自动微分模块是构成神经网络训练的必要模块&#xff0c;可以实现网络权重参数的更新&#xff0c;使得反向传播算法的实现变得简单而高效。 1.1 基础概念 1. 张量 &#xff1a…

Linux通用一键换源脚本.sh - ubuntu、centos全自动更换国内源 - LinuxMirrors神器

效果 脚本 bash <(curl -sSL https://linuxmirrors.cn/main.sh) 来自 https://linuxmirrors.cn/ 截图 ending...

【Python学习笔记】Pandas实现Excel质检记录表初审、复核及质检统计

背景&#xff1a; 我有这样一个需要审核的飞书题目表&#xff0c;按日期分成多个sheet&#xff0c;有初审——复核——质检三个环节&#xff0c;这三个环节是不同的同学在作业&#xff0c;并且领到同一个题目的人选是随机的&#xff0c;也就是说&#xff0c;完成一道题的三个人…

Gparted重新分配swap空间之后,linux电脑读不到swap空间

问题背景 lsblk 显示存在物理设备&#xff08;如 /dev/nvme0n1&#xff09;&#xff0c;但 swapon --show 无输出 说明 系统未启用任何 Swap 设备 问题原因分析 /etc/fstab 中 Swap 的 UUID 配置错误 从图片中看到执行 sudo swapon -a 时报错&#xff1a; swapoff: cannot fin…

第一节:Vben Admin 最新 v5.0初体验

系列文章目录 基础篇 第一节&#xff1a;Vben Admin介绍和初次运行 第二节&#xff1a;Vben Admin 登录逻辑梳理和对接后端准备 第三节&#xff1a;Vben Admin登录对接后端login接口 第四节&#xff1a;Vben Admin登录对接后端getUserInfo接口 第五节&#xff1a;Vben Admin权…

ARCGIS国土超级工具集1.5更新说明

ARCGIS国土超级工具集V1.5版本更新说明&#xff1a;因作者近段时间工作比较忙及正在编写ARCGISPro国土超级工具集&#xff08;截图附后&#xff09;的原因&#xff0c;故本次更新为小更新&#xff08;没有增加新功能&#xff0c;只更新了已有的工具&#xff09;。本次更新主要修…

CNN:卷积到底做了什么?

卷积神经网络&#xff08;Convolutional Neural Network, CNN&#xff09; 是一种深度学习模型&#xff0c;专门用于处理具有网格结构的数据&#xff08;如图像、视频等&#xff09;。它在计算机视觉领域表现卓越&#xff0c;广泛应用于图像分类、目标检测、图像分割等任务。CN…

AI应用开发之扣子第二课-AI翻译(第1节/共2节)

简介 共分为两节介绍&#xff0c;内容简单易懂&#xff0c;步骤详细&#xff0c;可以避免很多坑&#xff0c;建议直接上手操作&#xff08;预估30分钟&#xff09;。 AI应用开发之扣子第二课学习-AI翻译&#xff08;第1节/共2节&#xff09;&#xff1a;业务逻辑实现 AI应用…

linux学习 3.用户的操作

用户 建议在系统操作的时候不要一直使用root用户&#xff0c;因为root用户具有最高权限&#xff0c;你可能因为某些操作影响了你的系统&#xff0c;采用子用户则可以避免这一点 这里的学习不用太深入&#xff0c;掌握如何创建删除切换即可(除非你要做详细的用户管理&#xff0…

Leetcode刷题 由浅入深之哈希表——242. 有效的字母异位词

目录 &#xff08;一&#xff09;字母异位词的C实现 写法一&#xff08;辅助数组&#xff09; &#xff08;二&#xff09;复杂度分析 时间复杂度 空间复杂度 &#xff08;三&#xff09;总结 【题目链接】242.有效的字母异位词 - 力扣&#xff08;LeetCode&#xff09; …