服务提供者接口(SPI)和应用程序编程接口(API)有什么区别?
更具体地说,对于Java库,是什么使它们成为API和/或SPI?
服务提供者接口(SPI)和应用程序编程接口(API)有什么区别?
更具体地说,对于Java库,是什么使它们成为API和/或SPI?
当前回答
服务提供者接口是所有提供者都必须实现的服务接口。如果现有的提供者实现都不适合您,那么您需要编写自己的服务提供者(实现服务接口)并在某处注册(请参阅Roman的有用文章)。
如果重用服务接口的现有提供者实现,基本上就是在使用该特定提供者的API,其中包括服务接口的所有方法以及它自己的一些公共方法。如果您在SPI之外使用提供者API的方法,那么您使用的是提供者特定的特性。
其他回答
API代表应用程序编程接口,其中API是访问某种软件或平台提供的服务/功能的手段。
SPI代表服务提供者接口(Service Provider Interface), SPI是为软件或平台注入、扩展或改变行为的方法。
API通常是客户端访问服务的目标,它具有以下属性:
>API是一种访问服务以实现特定行为或输出的编程方式
从API发展的角度来看,添加对客户端来说根本不是问题
但是API一旦被客户端使用,它就不能(也不应该)被修改/删除 除非有适当的沟通,否则就彻底退化了 客户的期望
另一部分的SPI是针对提供者的,具有以下属性:
——>SPI是一种扩展/改变软件或平台行为的方法(可编程vs。 编程)
->SPI的进化不同于API的进化,SPI的移除不是一个问题
添加SPI接口会导致问题,可能会破坏现有的实现
更多解释请点击这里:服务提供者接口
我认为SPI通过实现API的某些特性,然后通过服务查找机制将自身注册为可用,从而嵌入到更大的系统中。API由最终用户应用程序代码直接使用,但可以集成SPI组件。这就是封装和直接使用之间的区别。
在Java世界中,不同的技术都是模块化的,并且可以“插入”到应用服务器中。这两者之间是有区别的
应用服务器 (SPI) 可插拔技术 (API) 最终用户应用程序
这类技术的两个例子是JTA(事务管理器)和JCA (JMS或数据库适配器)。但还有其他原因。
这种可插技术的实现者必须在应用程序服务器中实现可插的SPI,并提供供最终用户应用程序使用的API。来自JCA的一个例子是ManagedConnection接口,它是SPI的一部分,而Connection是最终用户API的一部分。
有一个方面似乎没有被强调太多,但对于理解为什么以及何时使用API/SPI非常重要。
API/SPI的分离只在你实际编写一个平台时才需要,而且它预计会不断发展。如果你写了一个API,并且“知道”它将来不需要任何向后兼容的改进,那么就没有真正的理由把你的代码分成两部分。此外,如果你根本不写平台(你有所有的API消费者代码在控制之下),唯一的好处将是良好和干净的对象设计,因为你可以在任何时候重构你需要的东西。
但是,一旦您的平台至少有一个第三方客户端,并且您希望以向后兼容的方式进行更改,那么您很可能应该使用API/SPI拆分。
让我们在一个众所周知的Java对象Collection和Collections上展示它。
Collections是一组实用程序静态方法。通常表示API对象的类被定义为final,因为它确保(在编译时)没有客户端可以“实现”该对象,并且它们可以依赖于“调用”其静态方法。
Collections.emptySet();
因为所有的客户端都是“调用”而不是“实现”,JDK的作者可以在未来版本的JDK中自由地向Collections对象中添加新方法。他们可以确定它不会破坏任何客户端,即使可能有数百万的使用。
SPI:集合是一个接口,它意味着任何人都可以实现自己的版本。因此,JDK的作者不能向其中添加新方法,因为这会破坏所有编写自己的Collection实现(*)的客户端。
通常情况下,当需要添加额外的方法时,需要创建新的接口,如Collection2,它是对前者的扩展。然后SPI客户端可以决定是否迁移到新版本的SPI并实现它的附加方法,或者是否坚持使用旧的方法。
你可能已经看到了这一点。如果你把这两个部分合并到一个类中,你的API将被阻止任何添加。这也是为什么优秀的Java api和框架不公开抽象类的原因,因为它们会阻碍它们未来在向后兼容性方面的发展。
如果还有什么不清楚的地方,我建议你去看看这个页面,上面有更详细的解释。
(*)注意,这只适用于Java 1.8,它引入了在接口中定义默认方法的概念。
API是类/接口/方法/…你用它来实现目标,还有 SPI是类/接口/方法的描述…你通过扩展和实现来实现一个目标。
换句话说,API告诉你一个特定的类/方法为你做了什么,而SPI告诉你必须做什么才能符合。
通常API和SPI是分开的。例如,在JDBC中,驱动程序类是SPI的一部分:如果你只是想使用JDBC,你不需要直接使用它,但是每个实现JDBC驱动程序的人都必须实现这个类。
然而,有时它们会重叠。Connection接口既是SPI也是API:当您使用JDBC驱动程序时,您通常会使用它,并且它需要由JDBC驱动程序的开发人员实现。