Service Provider Interface (SPI) is a technology from the standard JavaSE distribution. It implements
Inversion of Control (IoC) without being Dependency Injection (DI). With SPI, you can easily provide specific service implementations through separate JAR files without additional tools. Its use often resembles a plugin mechanism.
The two main concepts of SPI are the service and the service provider. A
service is an interface or abstract class that declares the API of the required service and is provided by the main application. A
service provider is the implementation of this API, a subclass of the service class/interface, which is dynamically delivered to the main application via a plugin library. Multiple providers for a single service can be supplied from one or several libraries.
There are no restrictions on the service interface. However, the provider must implement this interface and have a no-argument constructor. Inside the JAR file, in the
META-INF/services
directory, there are text files where the filename is the fully qualified name of the service, and each line inside the file lists the fully qualified names of the providers of that service supplied by the library.
To obtain providers from all libraries in the application, the
ServiceLoader
class is used. It is an iterator over service providers, created by the static
load
method, which takes the interface or abstract class of the desired service as a parameter.
Access to resource files from the classpath is provided by the
class loader, so you can also specify a specific loader during loading. With the introduction of modularity in Java 9, you can also specify a module.
SPI is widely used in the standard JDK library. It is used to connect
JDBC drivers.
ServiceLoader
is also used to load time zones, system settings, encodings, file system providers, and much more.