微服务feign接口声明的3种方式使用与分析
创始人
2024-04-09 00:30:28

前言

feign调用方式是微服务调用最为广泛的使用方式,feign接口声明位置也是比较关键的一环。目前来说,feign的3种接口声明方式各自存在利弊,并不存在最优解决方案,只能根据需求去选择。本文中不作详细项目搭建过程,但并非无码之谈,阅读前请认真阅读项目说明。

项目说明

案例项目中有两个项目,分别是用户(user-service-nacos)与订单(order-service-nacos)。用户是服务提供者,订单是消费者。
user-service-nacos中只有一个接口findById,返回一串随机数

@RestController
public class UserController {@GetMapping("/user/{id}")public String findById(@PathVariable("id") String id) {Random r = new Random();return "user/id: " + id + r.nextInt();}}

order-service-nacos有一个接口会去调用user-service-nacos的findById

@RestController
public class OrderController {@Autowiredprivate UserClient userClient;@GetMapping("/order/{id}")public String findById(Long id) {String byId = userClient.findById("9");return "userClient return value : " + byId;}
}

代码很简单,我们要探讨的问题就是上面的UserClient的feign接口声明放置的位置的用法与利弊

方式一:消费者中单独声明

在order-service-nacos中单独声明一个UserClient接口

@FeignClient("user-service")
public interface UserClient {@GetMapping("/user/{id}")String findById(@PathVariable("id") String id);}

调用结果:
在这里插入图片描述

优劣分析

使用在消费者单独声明的方式,写法简单,代码耦合度低,可用于不处于同一个工程下的应用。但存在问题也是很明显,需要维护两个地方一模一样的代码,订单服务中的UserClient的声明其实和UserController声明的接口是一模一样的,而且必须要一模一样的,这就造成了代码冗余和维护的不便。

方式二

基于方式一的探讨,我们很容易想到,一模一样的代码,而且冗余,那解决方案很简单呀,抽方法,定义一个公共接口,让服务者与消费者都继承接口。
定义一个公共的接口:UserAPI

public interface UserAPI {@GetMapping("/user/{id}")String findById(@PathVariable("id") String id);
}

订单服务中,UserClient直接继承了这个接口,方法不用手动编写

@FeignClient("user-service")
public interface UserClient extends UserAPI {}

用户服务中,UserController去实现接口中的方法

@RestController
public class UserController implements UserAPI {@GetMapping("/user/{id}")@Overridepublic String findById(@PathVariable("id") String id) {Random r = new Random();return "user/id: " + id + r.nextInt();}}

优劣分析

这样的做法有效避免了方式一中的缺陷,但由于提供者与消费者共用同一个接口,造成了紧耦合关系,如果UserAPI接口发生变动,提供者与消费者两端都受到影响,也无法作用于隔离开的两个工程项目。而且spring mvc继承的方式无法继承参数映射的注解,如上面的@PathVariable。尽管这种方式有缺点,但是也是遵循了面向契约的编程思想,在企业中有广泛的使用。

提出问题

假设有很多个微服务都要调用用户服务,那岂不是要在各个服务中都定义一个UserClient?如果在同一个父级pom文件下,你会想到将UserClient抽出来作为一个单独的module,这就是方式三的基本思想。

方式三:抽取独立模块

将FeignClient抽取为独立模块,并且把接口相关的实体类(pojo)、默认的Feign配置都放到这个模块中,提供给所有消费者使用。

创建一个单独module,引入feign依赖,将UserClient复制到此处。我这里的案例比较简单,没有pojo,如果说接口返回的是一个对象,那么这个对象应该声明在下面pojo包中(也可以是dto)。其它地方使用时,需要导入该模块,注意配置好springboot的包路径扫描。
在这里插入图片描述
通常来说,feign-api模块最好是放置在服务提供者工程中,方便管理。若提供者与消费者属于同一个工程,则可直接引入pom文件。否则,则需要执行maven的package命令将feign-api打成jar包才能被消费者使用。

优劣分析

这种方式有效降低耦合度,并减少重复开发的工作,但也存在一定问题,假设定义的feign-api module中有大量的接口类,消费者只需要其中一两个接口,但是导入了比较多的类,存在冗余。相对而言,这种方式是feign的最佳实践方式。

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...