What is the difference between Service Provider Interface (SPI) and Application Programming Interface (API)?

More specifically, for Java libraries, what makes them an API and/or SPI?

  • The API is the description of classes/interfaces/methods/... that you call and use to achieve a goal, and
  • the SPI is the description of classes/interfaces/methods/... that you extend and implement to achieve a goal.

Put differently, the API tells you what a specific class/method does for you, and the SPI tells you what you must do to conform.

Usually API and SPI are separate. For example, in JDBC the Driver class is part of the SPI: If you simply want to use JDBC, you don't need to use it directly, but everyone who implements a JDBC driver must implement that class.

Sometimes they overlap, however. The Connection interface is both SPI and API: You use it routinely when you use a JDBC driver and it needs to be implemented by the developer of the JDBC driver.

  • sounds about right. its just that the lines between SPI & API can be a little grey as most API has abstract classes/interfaces for its user to implement to get things done as well... – kctang Jun 2 '10 at 14:02
  • 1
    @koss: most API? I know what you mean, but I don't see those things a lot. – Joachim Sauer Jun 2 '10 at 14:05
  • 2
    API is more relevent to developers while SPI is to vendors. – Azfar Niaz Apr 19 '14 at 8:56
  • 4
    @AzfarNiaz: well, since vendors employ developers to build their products both are relevant to developers ;-) – Joachim Sauer Jan 20 '15 at 17:25
  • In Java, are annotations part of an SPI? For example, if I have to add @SomeAnnotation to my class to get it picked up by some framework, would this annotation class SomeAnnotation.class be considered part of the SPI, even though I am not technically extending or implementing it? – Kidburla Nov 22 '16 at 16:39

From Effective Java, 2nd Edition:





// 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 {

    // 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();
  • 3
    thanks for the very nice description on service provider framework. this will be useful to know. however, it does not clearly describe "difference" between api & spi so i won't put a tick here... ;-) – kctang Jun 2 '10 at 14:06

API stands for Application Programming Interface, where API is a means for accessing a service / function provided by some kind of software or a platform.

SPI stands for Service Provider Interface, where SPI is way to inject, extend or alter the behavior for software or a platform.

API is normally target for clients to access a service and it has the following properties:

-->API is a programmatic way of accessing a service to achieve a certain behavior or output

-->From API evolution point of view, addition is no problem at all for clients

-->But API's once utilized by clients it can not (and should not) be altered / deleted unless there are an appropriate communications, since its a complete degradation of the client expectation

SPI on the other part are targeted for providers and has the following properties:

-->SPI is a way to extend / alter the behavior of a software or a platform (programmable vs. programmatic)

-->SPI evolution is different from API evolution, in SPI removal is not an issue

-->Addition of SPI interfaces will cause problems and may break existing implementations

For more explanation click here : Service Provider Interface


The difference between API and SPI comes when an API additionally provides some concrete implementations. In that case, the service provider has to implement a few APIs (called SPI)

An example is JNDI:

JNDI provides interfaces & some classes for context lookup. The default way to lookup a context is provided in IntialContext. This class internally will use SPI interfaces (using NamingManager) for provider specific implementations.

See the JNDI Architecture below for better understanding.

Enter image description here


NetBeans' FAQ: What is an SPI? How is it different from an API?



The classic example is JavaMail. Its API has two sides:





I suppose an SPI slots into a larger system by implementing certain features of an API, and then registering itself as being available via service lookup mechanisms. An API is used by the end-user application code directly, but may integrate SPI components. It's the difference between encapsulation and direct usage.

  • thanks for the response chris. any examples of existing Java (i.e. Servlet, JDBC, etc) libraries? ...like how it makes them API/SPI. can be hard to visualize the difference with description alone. – kctang Jun 2 '10 at 1:14
  • 1
    An API is JDBC, an SPI for JDBC is the database connector interface which SPI developers can use to create new database connectors which the developer can select for usage. – Chris Dennett Jun 2 '10 at 1:39

Service provider interface is the service interface which all providers must implement. If none of the existing provider implementations work for you, you need to write your own service provider (implementing the service interface) and register somewhere (see the useful post by Roman).

If you're reusing the existing provider implementation of the service interface, you're basically using the API of that particular provider, which include all the methods of service interface plus a few public methods of its own. If you're using methods of provider API outside the SPI, you're using provider specific features.


There is one aspect which doesn't seem to be highlighted much but is very important to understand the reasoning behind the existence of API/SPI split.

API/SPI split is only required when platform is expected to evolve. If you write an API and "know" it won't require any future improvements ever, there is no real reasons for splitting your code into the two parts (besides making clean object design).

But this is almost never the case and people need to have a freedom to evolve API together with future requirements - in a backward compatible way.

Note that all of the above assumes you're building platform that other people use and/or extend and not your own API where you have all client code under control and thus can refactor however you need.

Lets show it on one of the well known Java objects Collection and Collections.

API: Collections is a set of utility static methods. Often classes representing API object are defined as final as it ensures (at compilation time) that no client can ever "implement" that object and they can depend on "calling" its static methods, e.g.


Since all clients are "calling" but not "implementing", authors of JDK are free to add new methods into the Collections object in the future version of JDK. They can be sure it can't break any client, even if there are probably milions of usages.

SPI: Collection is an interface which implies that anyone can implement her own version of it. Thus, authors of JDK can't add new methods into it as it would break all clients who wrote their own Collection implementation (*).

Typically when additional method is required to be added, new interface, e.g. Collection2 which extends the former one needs to be created. SPI client then can decide whether to migrate to the new version of SPI and implement it's additional method or whether to stick with the older one.

You might already seen the point. If you combine both pieces together into a single class, your API is blocked from any additions. That's also the reason why good Java APIs and Frameworks don't expose abstract class as they would block their future evolution with respect to the backward compatibility.

If something is still unclear, I recommend to check this page which explains the above in more detail.

(*) Note this is true only until Java 1.8 which introduces concept of default methods defined in an interface.


In the Java world, different technologies are meant to be modular and "pluggable" into an application server. There is then a difference between

  • the application server
    • [SPI]
  • the pluggable technology
    • [API]
  • the end user application

Two examples of such technologies are JTA (the transaction manager) and JCA (adapter for JMS or database). But there are others.

Implementer of such a pluggable technology must then implement the SPI to be pluggable in the app. server and provide an API to be used by the end-user application. An example from JCA is the ManagedConnection interface which is part of the SPI, and the Connection that is part of the end-user API.

protected by Maroun Nov 12 '13 at 13:27


Would you like to answer one of these unanswered questions instead?
