服务提供商接口 (SPI) 和 应用程序编程接口 (API) 有什么区别?
更具体地说,对于 Java 库,是什么使它们成为 API 和/或 SPI?
原文由 kctang 发布,翻译遵循 CC BY-SA 4.0 许可协议
服务提供商接口 (SPI) 和 应用程序编程接口 (API) 有什么区别?
更具体地说,对于 Java 库,是什么使它们成为 API 和/或 SPI?
原文由 kctang 发布,翻译遵循 CC BY-SA 4.0 许可协议
来自 _Effective Java,第 2 版_:
服务提供者框架是一个系统,其中多个服务提供者实现了一项服务,并且该系统使实现对其客户端可用,从而将它们与实现解耦。
服务提供者框架包含三个基本组件:提供者实现的服务接口;提供者注册 API,系统使用它来注册实现,让客户可以访问它们;和一个服务访问 API,客户端使用它来获取服务的实例。服务访问 API 通常允许但不要求客户端指定一些选择提供者的标准。如果没有这样的规范,API 将返回一个默认实现的实例。服务访问 API 是构成服务提供者框架基础的“灵活静态工厂”。
服务提供者框架的第四个可选组件是服务提供者接口,提供者实现该接口以创建其服务实现的实例。在没有服务提供者接口的情况下,实现通过类名注册并以反射方式实例化(条目 53)。在 JDBC 的情况下,Connection 扮演服务接口的角色,DriverManager.registerDriver 是提供者注册 API,DriverManager.getConnection 是服务访问 API,Driver 是服务提供者接口。
服务提供者框架模式有许多变体。例如,服务访问 API 可以使用适配器模式 [Gamma95, p. 4] 返回比提供者所需的服务接口更丰富的服务接口。 139]。这是一个带有服务提供者接口和默认提供者的简单实现:
// 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();
}
}
原文由 Roman 发布,翻译遵循 CC BY-SA 3.0 许可协议
15 回答8.4k 阅读
8 回答6.2k 阅读
1 回答4k 阅读✓ 已解决
3 回答2.2k 阅读✓ 已解决
2 回答3.1k 阅读
2 回答3.8k 阅读
3 回答1.7k 阅读✓ 已解决
换句话说,API 告诉您特定的类/方法为您做了什么,而 SPI 告诉您必须做什么才能符合。
通常API和SPI是分开的。例如,在JDBC 中
Driver
类 是SPI的一部分:如果你只是想使用JDBC,你不需要直接使用它,但是每个实现JDBC驱动程序的人都必须实现那个类。然而,有时它们会重叠。
Connection
接口 既是 SPI又是API:你在使用JDBC驱动时常规使用,需要JDBC驱动的开发者实现。