SPI和API区别

API直接为你提供了功能,你使用API就能完成任务。
         SPI是一种回调的思想,回调是指我们在使用api时,我们可以向api传入一个类或者方法,api在合适的时间调用类或者方法。SPI是在一些通用的标准中,为标准的实现产商提供的扩展点。标准在上层提供API,API内部使用了SPI,当API被客户使用时,会动态得从当前运行的classpath中寻找该SPI的实现,然后使用该SPI的实现来完成API的功能。
         SPI的实现方式是:提供实现的实现类打包成Jar文件,这个Jar文件里面必须有META-INF目录,其下又有services目录,其下有一个文本文件,文件名即为SPI接口的全名,文件的内容该jar包中提供的SPI接口的实现类名。

背景

Java 中区分 API 和 SPI,通俗的讲:API 和 SPI 都是相对的概念,他们的差别只在语义上,API 直接被应用开发人员使用,SPI 被框架扩展人员使用

理解

API Application Programming Interface

大多数情况下,都是实现方来制定接口并完成对接口的不同实现,调用方仅仅依赖却无权选择不同实现。

SPI Service Provider Interface

而如果是调用方来制定接口,实现方来针对接口来实现不同的实现。调用方来选择自己需要的实现方

More specifically, for Java libraries, what makes them an API and/or SPI?

the API is the description of classes/interfaces/methods/... that you call and use to achieve a goal

the SPI is the description of classes/interfaces/methods/... that you extend and implement to achieve a goal

Put differently, the API tells you what a specific class/method does for you and the SPI tells you what you must do to conform.

从面向接口编程说起

接口调用.jpg

当我们选择在调用方实现方 中间引入 接口。上图没有给出“接口”应该位于哪个“包”中,从纯粹的可能性上考虑,我们有三种选择:

  1. 接口位于实现方所在的包中
  2. 接口位于调用方所在的包中
  3. 接口位于独立的包中

接口位于调用方所在的包中

对于类似这种情况下接口,我们将其称为 SPI, SPI的规则如下:

  • 概念上更依赖调用方。
  • 组织上位于调用方所在的包中。
  • 实现位于独立的包中。

常见的例子是:插件模式的插件。如:

  1. 数据库驱动 Driver
  2. 日志 Log
  3. dubbo扩展点开发

接口位于实现方所在的包中

对于类似这种情况下的接口,我们将其称作为APIAPI的规则如下:

  • 概念上更接近实现方。
  • 组织上位于实现方所在的包中。

接口位于独立的包中

如果一个“接口”在一个上下文是API,在另一个上下文是SPI,那么你就可以这么组织

需要注意的事项

SPIAPI 也不一定是接口,我这里都是指狭义的具体的接口。

另外一张图

SPI和API区别.png



作者:faris_shi
链接:https://www.jianshu.com/p/7e85b8ed00e2
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

“接口”位于“调用方”所在的“包”中

我们先想象一个场景,以仓储的接口为例:

 

我们将“仓储接口”放置于“领域层”这个“包”中,实现放在一个独立的“包”中,我们看DDD大师的实现都是这样子,现在来思考一下为什么这么做。

“领域层”的“领域服务”会依赖“仓储接口”,“仓储接口”也会依赖“聚合根”,这两者都是除了“实现依赖”之外的依赖关系,如果将“接口”放到“仓储实现”中就丧失了面向接口编程的意义(编译也不会通过),如果放到“独立层”中呢?会编译不通过,出现双向依赖了。

对于类似这种情况下接口,我们将其称为“SPI”,全程为:service provider interface,“SPI”的规则如下:

  1. 概念上更依赖调用方。
  2. 组织上位于调用方所在的包中。
  3. 实现位于独立的包中。
  4. 常见的例子是:插件模式的插件。

 

因此,可清楚知道,API是你可以引用来达成某个目标的对象,它清楚地告诉你它可以完成什么目标,用户可以即插即用;而SPI则指定了你要达成某个目标你必须要继承或实现它,它一般只供某些特殊用途的接口开发商使用(当然,有些公司或个人也可以自己继承或实现SPI来完成特定功能)。

有时候,API和SPI是分不清的,比如Connection接口,Driver接口等。

 

 

  • 5
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值