写本篇主要是用来后面写一篇可扩展性软件设计打好基础(苦于找不到一篇关于API/SPI的好文章,只好自己写一个,欢迎指教)。 
概念: 
API:API(Application Programming Interface)表示应用程序编程接口 
SPI:SPI(Service Provider Interface)表示服务提供商接口 
API与SPI的关系 
框架提供API及其实现,框架在实现过程中提供SPI回调机制。SPI是框架的扩展点。如果使用框架方要扩展框架,可以自己实现SPI并注入框架,于是框架使用方其实也是一个服务提供商。

SPI实现有两种方式,一种是第三方提供实现,另一种是应用自身自己提供实现 
看一下API/SPI关系图1,第三方提供商实现了SPI,应用引入第三方提供商的第三方库 

举例 
java中JDBC是一个编程接口,而Driver是一个SPI,同时不同数据库厂商会提供Driver的实现。应用中要使用JDBC编程接口时需要引入第三方数据库厂商驱动包,第三方厂商提供的驱动包其实就是SPI的实现。

看一下API/SPI关系图1,应用自身为了扩展框架自己实现了SPI,直接在自己的应用包里实现SPI 

举例 
我写了一个RenderAPI用来渲染vm模板, 渲染逻辑过程中会默认引入PullTool让vm中可以使用,如DateUtil,StringUtil等。应该可能想引入自己的业务PullTool,如MoneyTool等。于是我可以在RenderAPI接口的实现里,读取PullToolFacotry这个SPI,从这个SPI返回的PullTool加入到渲染引擎里。PullToolFacotry接口里就一个方法public Map<String PullTool> getPullTools();应用端可以写个类叫BusinessPullToolFactoryImpl实现PullToolFactory,把自己想要加入的PullTool返回即可。 

框架如何发现SPI?
 
框架可以使用java提供的java.util.ServiceLoader类得到SPI的实现。 
如ServiceLoader<PullToolFactory> pullToolFactorys     = ServiceLoader.load(PullToolFactory.class);

应用或第三方提供商如何注入SPI实现? 
应用或第三方包在jar包的META-INF/services/目录里同时创建一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类的完全限定名。而当框架调用ServiceLoader.load(PullToolFactory.class),就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并装载实例化,完成SPI实现的注入。

总结: 
可以想象,使用SPI设计,框架可以很容易引入扩展点,同时应用要扩展框架逻辑也很容易实现。框架可扩展设计可以基于这个原则进行设计扩展点。 

API/SPI可扩展设计原则(转)的更多相关文章

  1. javascript的api设计原则

    前言 本篇博文来自一次公司内部的前端分享,从多个方面讨论了在设计接口时遵循的原则,总共包含了七个大块.系卤煮自己总结的一些经验和教训.本篇博文同时也参考了其他一些文章,相关地址会在后面贴出来.很难做到 ...

  2. GOTO Berlin: Web API设计原则

    在邮件列表和讨论区中有很多与REST和Web API相关的讨论,下面仅是我个人对这些问题的一些见解,并没有绝对的真理,InnoQ的首席顾问Oliver Wolf在GOTO Berlin大会上开始自己的 ...

  3. Atitit.论图片类型 垃圾文件的识别与清理  流程与设计原则 与api概要设计 v2 pbj

    Atitit.论图片类型 垃圾文件的识别与清理  流程与设计原则 与api概要设计 v2 pbj 1. 俩个问题::识别垃圾文件与清理策略1 2. 如何识别垃圾图片1 2.1. 体积过小文件<1 ...

  4. 优秀的API接口设计原则及方法(转)

    一旦API发生变化,就可能对相关的调用者带来巨大的代价,用户需要排查所有调用的代码,需要调整所有与之相关的部分,这些工作对他们来说都是额外的.如果辛辛苦苦完成这些以后,还发现了相关的bug,那对用户的 ...

  5. 好RESTful API的设计原则

    说在前面,这篇文章是无意中发现的,因为感觉写的很好,所以翻译了一下.由于英文水平有限,难免有出错的地方,请看官理解一下.翻译和校正文章花了我大约2周的业余时间,如有人愿意转载请注明出处,谢谢^_^ P ...

  6. RESTful API的设计原则

    好RESTful API的设计原则   说在前面,这篇文章是无意中发现的,因为感觉写的很好,所以翻译了一下.由于英文水平有限,难免有出错的地方,请看官理解一下.翻译和校正文章花了我大约2周的业余时间, ...

  7. 好的RESTful API的设计原则

    转载自一位大佬 英文原版 Principles of good RESTful API Design Good API design is hard! An API represents a cont ...

  8. RESTful API设计原则与规范

    RESTful API设计原则与规范 一.背景与基础概念 2 二.RESTful API应遵循的原则 3 1.协议(Protocol) 3 2.域名(ROOT URL) 3 3.版本(Versioni ...

  9. 【JS】327- javascript 的 api 设计原则

    点击上方"前端自习课"关注,学习起来~ 前言 本篇博文来自一次公司内部的前端分享,从多个方面讨论了在设计接口时遵循的原则,总共包含了七个大块.系卤煮自己总结的一些经验和教训.本篇博 ...

随机推荐

  1. DHCP机制

    DHCP概念:局域网的网络协议,使用UDP协议工作,在工作过程中,它有两个对象,DHCP客户端和DHCP服务端,DHCP服务运行在67端口和68端口. 用途:1)个内部网络或网络服务供应商自动分配IP ...

  2. java把类似a=1&b=2&c=3的String类型数据转成map集合

    public static Map<String, Object> transStringToMap(String mapString, String separator, String ...

  3. Leetcode 993. 二叉树的堂兄弟节点

    993. 二叉树的堂兄弟节点  显示英文描述 我的提交返回竞赛   用户通过次数195 用户尝试次数229 通过次数195 提交次数462 题目难度Easy 在二叉树中,根节点位于深度 0 处,每个深 ...

  4. C# 语法特性 - 泛型(C#2.0)

    泛型将 类型参数 的概念引入了 .NET Framework. 泛型主要有两个优点: 1.编译时可以保证类型安全. 2.不用做类型转换,获得一定的性能提升. 泛型方法.泛型委托.泛型接口 除了泛型类之 ...

  5. vue element-ui 通过v-for渲染的el-form-item组件,使用自带的表单验证

    HTML: <el-form ref="newTermDetail" :model="newTermDetail" class="auto_fo ...

  6. Elasticsearch安装部署(CentOS)

    1.安装JDK,http://www.cnblogs.com/zhi-leaf/p/5996287.html. 2.下载ES:https://www.elastic.co/downloads/elas ...

  7. Minimum supported Gradle version is 4.1. Current version is 2.14.1

    Error:Minimum supported Gradle version is 4.1. Current version is 2.14.1. If using the gradle wrappe ...

  8. Linux第二周作业

    通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的 1.进入vi编写C语言程序代码,首先必须输入命令vi main,c,其中main.c是文件名. 紧接着按esc键退出编辑状态,再输入一个 ...

  9. WINDOWS 端口查看

    查看Windows下所有使用的端口 netstat -ano 查看Windows下某一个特定的端口 netstat -ano | find "8080"   查看windows下所 ...

  10. 输出链表的倒数第K个值

    题目描述 输入一个链表,输出该链表中倒数第k个结点.   思路一:链表不能向前遍历,只能向后遍历.因此倒数第K个结点就是 正序的  :len(链表)-1-K的下一个.  注意,此处的思路与代码中具体实 ...