服务提供者接口(SPI)和应用程序编程接口(API)有什么区别?
更具体地说,对于Java库,是什么使它们成为API和/或SPI?
服务提供者接口(SPI)和应用程序编程接口(API)有什么区别?
更具体地说,对于Java库,是什么使它们成为API和/或SPI?
当前回答
我认为SPI通过实现API的某些特性,然后通过服务查找机制将自身注册为可用,从而嵌入到更大的系统中。API由最终用户应用程序代码直接使用,但可以集成SPI组件。这就是封装和直接使用之间的区别。
其他回答
摘自Effective Java,第二版:
A service provider framework is a system in which multiple service providers implement a service, and the system makes the implementations available to its clients, decoupling them from the implementations. There are three essential components of a service provider framework: a service interface, which providers implement; a provider registration API, which the system uses to register implementations, giving clients access to them; and a service access API, which clients use to obtain an instance of the service. The service access API typically allows but does not require the client to specify some criteria for choosing a provider. In the absence of such a specification, the API returns an instance of a default implementation. The service access API is the “flexible static factory” that forms the basis of the service provider framework. An optional fourth component of a service provider framework is a service provider interface, which providers implement to create instances of their service implementation. In the absence of a service provider interface, implementations are registered by class name and instantiated reflectively (Item 53). In the case of JDBC, Connection plays the part of the service interface, DriverManager.registerDriver is the provider registration API, DriverManager.getConnection is the service access API, and Driver is the service provider interface. There are numerous variants of the service provider framework pattern. For example, the service access API can return a richer service interface than the one required of the provider, using the Adapter pattern [Gamma95, p. 139]. Here is a simple implementation with a service provider interface and a default provider:
// Service provider framework sketch
// Service interface
public interface Service {
... // Service-specific methods go here
}
// Service provider interface
public interface Provider {
Service newService();
}
// Noninstantiable class for service registration and access
public class Services {
private Services() { } // Prevents instantiation (Item 4)
// Maps service names to services
private static final Map<String, Provider> providers =
new ConcurrentHashMap<String, Provider>();
public static final String DEFAULT_PROVIDER_NAME = "<def>";
// Provider registration API
public static void registerDefaultProvider(Provider p) {
registerProvider(DEFAULT_PROVIDER_NAME, p);
}
public static void registerProvider(String name, Provider p){
providers.put(name, p);
}
// Service access API
public static Service newInstance() {
return newInstance(DEFAULT_PROVIDER_NAME);
}
public static Service newInstance(String name) {
Provider p = providers.get(name);
if (p == null)
throw new IllegalArgumentException(
"No provider registered with name: " + name);
return p.newService();
}
}
API是类/接口/方法/…你用它来实现目标,还有 SPI是类/接口/方法的描述…你通过扩展和实现来实现一个目标。
换句话说,API告诉你一个特定的类/方法为你做了什么,而SPI告诉你必须做什么才能符合。
通常API和SPI是分开的。例如,在JDBC中,驱动程序类是SPI的一部分:如果你只是想使用JDBC,你不需要直接使用它,但是每个实现JDBC驱动程序的人都必须实现这个类。
然而,有时它们会重叠。Connection接口既是SPI也是API:当您使用JDBC驱动程序时,您通常会使用它,并且它需要由JDBC驱动程序的开发人员实现。
API代表应用程序编程接口,其中API是访问某种软件或平台提供的服务/功能的手段。
SPI代表服务提供者接口(Service Provider Interface), SPI是为软件或平台注入、扩展或改变行为的方法。
API通常是客户端访问服务的目标,它具有以下属性:
>API是一种访问服务以实现特定行为或输出的编程方式
从API发展的角度来看,添加对客户端来说根本不是问题
但是API一旦被客户端使用,它就不能(也不应该)被修改/删除 除非有适当的沟通,否则就彻底退化了 客户的期望
另一部分的SPI是针对提供者的,具有以下属性:
——>SPI是一种扩展/改变软件或平台行为的方法(可编程vs。 编程)
->SPI的进化不同于API的进化,SPI的移除不是一个问题
添加SPI接口会导致问题,可能会破坏现有的实现
更多解释请点击这里:服务提供者接口
在Java世界中,不同的技术都是模块化的,并且可以“插入”到应用服务器中。这两者之间是有区别的
应用服务器 (SPI) 可插拔技术 (API) 最终用户应用程序
这类技术的两个例子是JTA(事务管理器)和JCA (JMS或数据库适配器)。但还有其他原因。
这种可插技术的实现者必须在应用程序服务器中实现可插的SPI,并提供供最终用户应用程序使用的API。来自JCA的一个例子是ManagedConnection接口,它是SPI的一部分,而Connection是最终用户API的一部分。
我认为SPI通过实现API的某些特性,然后通过服务查找机制将自身注册为可用,从而嵌入到更大的系统中。API由最终用户应用程序代码直接使用,但可以集成SPI组件。这就是封装和直接使用之间的区别。