2024-01-04 05:00:02

SPI和API的区别?

服务提供者接口(SPI)和应用程序编程接口(API)有什么区别?

更具体地说,对于Java库,是什么使它们成为API和/或SPI?


当前回答

API是类/接口/方法/…你用它来实现目标,还有 SPI是类/接口/方法的描述…你通过扩展和实现来实现一个目标。

换句话说,API告诉你一个特定的类/方法为你做了什么,而SPI告诉你必须做什么才能符合。

通常API和SPI是分开的。例如,在JDBC中,驱动程序类是SPI的一部分:如果你只是想使用JDBC,你不需要直接使用它,但是每个实现JDBC驱动程序的人都必须实现这个类。

然而,有时它们会重叠。Connection接口既是SPI也是API:当您使用JDBC驱动程序时,您通常会使用它,并且它需要由JDBC驱动程序的开发人员实现。

其他回答

服务提供者接口是所有提供者都必须实现的服务接口。如果现有的提供者实现都不适合您,那么您需要编写自己的服务提供者(实现服务接口)并在某处注册(请参阅Roman的有用文章)。

如果重用服务接口的现有提供者实现,基本上就是在使用该特定提供者的API,其中包括服务接口的所有方法以及它自己的一些公共方法。如果您在SPI之外使用提供者API的方法,那么您使用的是提供者特定的特性。

API代表应用程序编程接口,其中API是访问某种软件或平台提供的服务/功能的手段。

SPI代表服务提供者接口(Service Provider Interface), SPI是为软件或平台注入、扩展或改变行为的方法。

API通常是客户端访问服务的目标,它具有以下属性:

>API是一种访问服务以实现特定行为或输出的编程方式

从API发展的角度来看,添加对客户端来说根本不是问题

但是API一旦被客户端使用,它就不能(也不应该)被修改/删除 除非有适当的沟通,否则就彻底退化了 客户的期望

另一部分的SPI是针对提供者的,具有以下属性:

——>SPI是一种扩展/改变软件或平台行为的方法(可编程vs。 编程)

->SPI的进化不同于API的进化,SPI的移除不是一个问题

添加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还提供了一些具体的实现。在这种情况下,服务提供者必须实现一些api(称为SPI)

一个例子是JNDI:

JNDI为上下文查找提供了接口和一些类。在IntialContext中提供了默认的查找上下文的方法。该类将在内部使用SPI接口(使用NamingManager)实现特定于提供者的实现。

为了更好地理解,请参阅下面的JNDI体系结构。

API是类/接口/方法/…你用它来实现目标,还有 SPI是类/接口/方法的描述…你通过扩展和实现来实现一个目标。

换句话说,API告诉你一个特定的类/方法为你做了什么,而SPI告诉你必须做什么才能符合。

通常API和SPI是分开的。例如,在JDBC中,驱动程序类是SPI的一部分:如果你只是想使用JDBC,你不需要直接使用它,但是每个实现JDBC驱动程序的人都必须实现这个类。

然而,有时它们会重叠。Connection接口既是SPI也是API:当您使用JDBC驱动程序时,您通常会使用它,并且它需要由JDBC驱动程序的开发人员实现。