https://en.wikipedia.org/wiki/Service_provider_interface
Service Provider Interface (SPI) is an API intended to be implemented or extended by a third party. It can be used to enable framework extension and replaceable components.
Creating Extensible Applications
Installed Extensions
Installed extensions are JAR files in the lib/ext directory of the Java Runtime Environment (JRE™) software.
https://weblogs.java.net/blog/2008/08/11/capability-pattern-future-proof-your-apis
http://harisankar-krishnaswamy.blogspot.com/2012/05/java-design-pattern-service-provider.html
https://dzone.com/articles/lightweight-application-development
http://cristian.sulea.net/blog.php?p=2015-08-07-api-vs-spi
http://mussabsharif.blogspot.ro/2011/08/api-vs-spi.html
Service Provider Interface (SPI) is an API intended to be implemented or extended by a third party. It can be used to enable framework extension and replaceable components.
Creating Extensible Applications
An extensible application is one that you can extend without modifying its original code base. You can enhance its functionality with new plug-ins or modules. Developers, software vendors, and customers can add new functionality or application programming interfaces (APIs) by adding a new Java Archive (JAR) file onto the application class path or into an application-specific extension directory.
- Service
- A set of programming interfaces and classes that provide access to some specific application functionality or feature. The service can define the interfaces for the functionality and a way to retrieve an implementation. In the word-processor example, a dictionary service can define a way to retrieve a dictionary and the definition of a word, but it does not implement the underlying feature set. Instead, it relies on a service provider to implement that functionality.
- Service provider interface (SPI)
- The set of public interfaces and abstract classes that a service defines. The SPI defines the classes and methods available to your application.
- Service Provider
- Implements the SPI. An application with extensible services enable you, vendors, and customers to add service providers without modifying the original application.
public class DictionaryService {
private static DictionaryService service;
private ServiceLoader<Dictionary> loader;
private DictionaryService() {
loader = ServiceLoader.load(Dictionary.class);
}
public static synchronized DictionaryService getInstance() {
if (service == null) {
service = new DictionaryService();
}
return service;
}
public String getDefinition(String word) {
String definition = null;
try {
Iterator<Dictionary> dictionaries = loader.iterator();
while (definition == null && dictionaries.hasNext()) {
Dictionary d = dictionaries.next();
definition = d.getDefinition(word);
}
} catch (ServiceConfigurationError serviceError) {
definition = null;
serviceError.printStackTrace();
}
return definition;
}
}
To register your service provider, you create a provider configuration file, which is stored in the
META-INF/services
directory of the service provider's JAR file. The name of the configuration file is the fully qualified class name of the service provider, in which each component of the name is separated by a period (.
), and nested classes are separated by a dollar sign ($
).
The provider configuration file contains the fully qualified class names of your service providers, one name per line. The file must be UTF-8 encoded. Additionally, you can include comments in the file by beginning the comment line with the number sign (
#
).
For example, to register the service provider
GeneralDictionary
create a text file named dictionary.spi.Dictionary
. This file contains one line:dictionary.GeneralDictionary
Installed Extensions
Installed extensions are JAR files in the lib/ext directory of the Java Runtime Environment (JRE™) software.
any JAR file in the lib/ext of the JRE directory is automatically treated by the runtime environment as an extension.
Since installed extensions extend the platform's core API, use them judiciously. They are rarely appropriate for interfaces used by a single, or small set of applications.
- 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
The java.util.spi package in JDK 1.6 defines some examples of a SPI:
- CurrencyNameProvider is an abstract class (service contract) for service providers that provide localized currency symbols for theCurrency class.
- TimeZoneNameProvider is an abstract class for service providers that provide localized time zone names for the TimeZone class.
A service provider implements the SPI and contains one or more concrete classes that implement or extend (subclass) the service type. A single SPI specification can have more than one provider. To promote loose coupling and information hiding, the provider class is typically not the entire provider itself but rather a proxy that contains enough functionality to decide whether the provider is able to satisfy a particular request.
You can install service providers by simply adding a new Java Archive (JAR) file that holds the provider classes to the application's classpath or by placing the JAR into any of the usual extension directories (jre/lib/ext).
You identify a service provider by placing a provider-configuration file in the resource directory META-INF/services. The file's name is the fully qualified binary name of the service's type. The file contains a list of fully qualified binary names of concrete provider classes, one per line.
ServiceLoader maintains a cache of the providers that have been loaded. The only requirement this facility enforces is that every provider class must have a zero-argument constructor, so that it can be instantiated during loading. Providers are located and instantiated on demand.
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.
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
http://blog.jooq.org/2015/05/21/do-not-make-this-mistake-when-developing-an-spi/https://weblogs.java.net/blog/2008/08/11/capability-pattern-future-proof-your-apis
http://harisankar-krishnaswamy.blogspot.com/2012/05/java-design-pattern-service-provider.html
https://dzone.com/articles/lightweight-application-development
http://cristian.sulea.net/blog.php?p=2015-08-07-api-vs-spi
http://mussabsharif.blogspot.ro/2011/08/api-vs-spi.html
API stands for Application Programming Interface, and is a mean for accessing a service/function provided by some kind of software or a platform. API is normally target for clients to access a service and its 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 stands for Service Provider Interface, and is way to inject, extend or alter the behavior for software or a platform. SPI is 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 that SPI evolution, in SPI removal is not an issue.
- Addition of SPI interfaces will cause problems and may break existing implementations.
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. So:
- the API is the description of classes/interfaces/methods/... that you call and use to achieve a goal
- the SPI is the description of classes/interfaces/methods/... that you extend and implement to achieve a goal
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.