👉 这是一个或许对你有用的社群
🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入「芋道快速开发平台」知识星球。下面是星球提供的部分资料:
《项目实战(视频)》:从书中学,往事上“练”
《互联网高频面试题》:面朝简历学习,春暖花开
《架构 x 系统设计》:摧枯拉朽,掌控面试高频场景题
《精进 Java 学习指南》:系统学习,互联网主流技术栈
《必读 Java 源码专栏》:知其然,知其所以然

👉这是一个或许对你有用的开源项目
国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。
功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号、CRM 等等功能:
Boot 仓库:https://gitee.com/zhijiantianya/ruoyi-vue-pro
Cloud 仓库:https://gitee.com/zhijiantianya/yudao-cloud
视频教程:https://doc.iocoder.cn
【国内首批】支持 JDK 21 + SpringBoot 3.2.2、JDK 8 + Spring Boot 2.7.18 双版本
来源:www.cnblogs.com/happy
framework/p/3325560.html
背景
第一次听说 SPI 是阅读《软件框架设计的艺术》,以后陆续在 JDBC 和 SpringBoot 中发现了以这种形式组织代码的方式,本位给出为什么要区分 SPI 和 API 的一个思考过程。
基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
项目地址:https://github.com/YunaiV/ruoyi-vue-pro
视频教程:https://doc.iocoder.cn/video/
从面向接口编程说起
我们在“调用方”和“实现方”之间引入了“接口”,上图没有给出“接口”应该位于哪个“包”中,从纯粹的可能性上考虑,我们有三种选择:
“接口”位于“调用方”所在的“包”中。
“接口”位于“实现方”所在的“包”中。
“接口”位于独立的“包”中。
下面让我们依次分析这三种可能性,如果现实中确实有这种可能性,不如我们就为其起个名字以方便交流。
基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能
项目地址:https://github.com/YunaiV/yudao-cloud
视频教程:https://doc.iocoder.cn/video/
“接口”位于“调用方”所在的“包”中
我们先想象一个场景,以仓储的接口为例:
我们将“仓储接口”放置于“领域层”这个“包”中,实现放在一个独立的“包”中,我们看DDD大师的实现都是这样子,现在来思考一下为什么这么做。
“领域层”的“领域服务”会依赖“仓储接口”,“仓储接口”也会依赖“聚合根”,这两者都是除了“实现依赖”之外的依赖关系,如果将“接口”放到“仓储实现”中就丧失了面向接口编程的意义(编译也不会通过),如果放到“独立层”中呢?会编译不通过,出现双向依赖了。
对于类似这种情况下接口,我们将其称为“SPI”,全程为:service provider interface,“SPI”的规则如下:
概念上更依赖调用方。
组织上位于调用方所在的包中。
实现位于独立的包中。
常见的例子是:插件模式的插件。
“接口”位于“实现方”所在的“包”中
我们先想象一个场景,以Unity提供的IUnityContainer接口为例,除了维护这个框架的团队之外,我们没有发现谁实现了这个接口,虽然理论上是可以实现这个接口的(如果能实现的话,我们何不自己弄额Ioc容器呢?)。
对于类似这种情况下的接口,我们将其称作为“API”,“API”的规则如下:
概念上更接近实现方。
组织上位于实现方所在的包中。
实现和接口在一个包中。
“接口”位于独立的“包”中
这里就不说场景了,如果一个“接口”在一个上下文是“API”,在另一个上下文是“SPI”,那么你就可以这么组织。
需要注意的事项
不管是 SPI 或 API,接口都是可以组织到独立的“包”中,这么做是否有意义,自己来做出决定了。
SPI 和 API 也不一定是接口,我这里都是指狭义的具体的接口。
场景图
每一次思考都伴随着收获,也离不开和朋友们的交流,天更蓝了。
SPI 接口:
定义 :SPI 是一种服务提供者接口,它允许在运行时加载不同的服务实现。
使用场景 :
模块化设计 :当系统需要高度模块化,且希望将核心功能与具体实现分离时。
可插拔架构 :需要支持多种服务实现,并且可以在不修改代码的情况下替换或增加新的服务实现。
服务发现 :在运行时根据配置或服务注册表动态发现和加载服务。
微服务架构 :在微服务架构中,SPI 可用于服务间的动态交互和集成。
优点 :
提供了一种机制来在运行时选择和加载服务实现,增加了系统的灵活性和可扩展性。
支持服务的热插拔,无需重启系统即可更换服务实现。
API 接口:
定义 :API 是一组预定义的函数、协议和工具,用于构建软件应用,它定义了软件组件之间交互的契约。
使用场景 :
客户端和服务器交互 :当需要设计客户端和服务器之间的通信协议时。
库和框架 :提供给开发者使用的库或框架的公共接口。
第三方集成 :需要与第三方系统或服务进行集成。
内部组件通信 :在大型系统中,不同组件或模块之间的交互。
优点 :
为开发者提供了清晰的接口文档和规范,易于理解和使用。
有助于保持系统的稳定性,因为 API 变更需要遵循版本控制和兼容性规则。
促进了代码的重用和模块化。
如何选择?
选择使用 SPI 还是 API 的考虑因素:
扩展性 :如果需要在不修改代码的情况下扩展功能,SPI 更合适。
交互性 :API 更适合定义系统内部或系统之间的稳定交互接口。
动态性 :SPI 允许在运行时动态发现和加载服务,而 API 通常在编译时就已经确定。
安全性和稳定性 :API 由于其稳定性和可预测性,通常更受青睐。SPI 虽然灵活,但可能引入运行时错误。
版本控制和兼容性 :API 变更需要考虑版本控制和向后兼容性,而 SPI 可以通过服务版本协商来处理兼容性问题。
架构是“取舍”,而非“银弹”。
欢迎加入我的知识星球,全面提升技术能力。
👉 加入方式,“长按”或“扫描”下方二维码噢:

星球的内容包括:项目实战、面试招聘、源码解析、学习路线。





文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
437



被折叠的 条评论
为什么被折叠?



