写本篇主要是用来后面写一篇可扩展性软件设计打好基础(苦于找不到一篇关于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. LVS-概念

    一.负载均衡LVS基本介绍 LB集群的架构和原理很简单,就是当用户的请求过来时,会直接分发到Director Server上,然后它把用户的请求根据设置好的调度算法,智能均衡地分发到后端真正服务器(r ...

  2. 【IDEA】【4】遇到的问题

    前言: 1,jar包未导入到项目中 2,报错 cannot resolve symbol 3,左边栏只能看到文件看不到项目结构 4,报错 No valid Maven installation fou ...

  3. linux配置hadoop集群

    ①安装虚拟机 ②为虚拟机添加共享文件 右击已经安装好的虚拟机 设置—>选项—>共享文件 ③配置映射 sudo nano /etc/network/interfaces   重启网络:sud ...

  4. java getInstance()的使用

    转自:https://www.cnblogs.com/roadone/p/7977544.html 对象的实例化方法,也是比较多的,最常用的方法是直接使用new,而这是最普通的,如果要考虑到其它的需要 ...

  5. oracle中rownum和row_number()

    row_number()over(partition by col1 order by col2)表示根据col1分组,在分组内部根据col2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内 ...

  6. Node.js + Express中间件详解

    使用中间件 Express是一种路由和中间件Web框架,它具有自己的最小功能:Express应用程序本质上是一系列中间件函数调用. 中间件函数是可以访问请求对象 (req),响应对象(res)以及应用 ...

  7. xmanager运行报错:bash: /usr/bin/xterm: No such file or directory

    1.原因 xterm没有安装,解决办法是下载然后安装即可. 如果机器可以用yum,则直接使用yum安装xterm即可: yum install -y xterm 如果没有网络,则在某台操作系统大版本相 ...

  8. 线性回归决定系数之Why SST=SSE+SSR

    线性最小二乘法的原则是使得误差的平方和最小,即 为了使S最小,令其对参数的偏导数为零: 即 即 根据方程1和方程2,得 又∵ ∴ 参考链接:https://math.stackexchange.com ...

  9. oo作业总结报告2

    第五次作业 多线程电梯 多线程同步和控制的设计策略 明确类和对象,以及是否区分对象实例.具体类可以从类图中看出: 明确线程的类型和数量.输入作为一个线程,调度作为一个线程,三个电梯独立工作,互不影响, ...

  10. 【资料收集】PCA降维

    重点整理: PCA(Principal Components Analysis)即主成分分析,是图像处理中经常用到的降维方法 1.原始数据: 假定数据是二维的 x=[2.5, 0.5, 2.2, 1. ...