SPI 和 API 之间的区别?
服务提供商接口 (SPI) 和应用程序编程接口 (API) 之间有什么区别?
更具体地说,对于Java库,是什么使它们成为API和/或SPI?
服务提供商接口 (SPI) 和应用程序编程接口 (API) 之间有什么区别?
更具体地说,对于Java库,是什么使它们成为API和/或SPI?
来自 Effective Java, 2nd Edition:
服务提供者框架是一个系统,其中多个服务提供者实现一个服务,系统向其客户端提供实现,将它们与实现分离。
服务提供者框架有三个基本组成部分:服务接口,提供者实现;提供者注册API,系统使用它来注册实现,使客户端可以访问它们;和一个服务访问 API,客户端使用它来获取服务的实例。服务访问 API 通常允许但不要求客户端指定一些选择提供程序的条件。在没有此类规范的情况下,API 将返回默认实现的实例。服务访问 API 是构成服务提供程序框架基础的“灵活静态工厂”。
服务提供程序框架的可选第四个组件是服务提供程序接口,提供程序实现该接口以创建其服务实现的实例。在没有服务提供者接口的情况下,实现按类名注册并反射式实例化(项目 53)。在JDBC的情况下,连接扮演服务接口的角色,DriverManager.registerDriver是提供者注册API,DriverManager.getConnection是服务访问API,Driver是服务提供者接口。
服务提供程序框架模式有许多变体。例如,服务访问 API 可以使用适配器模式 [Gamma95,第 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();
}
}