library
advancedServiceLoader & SPI (Service Provider Interface)
Use Java's built-in plugin mechanism to discover and load implementations at runtime.
ServiceLoader (Java 6, enhanced in Java 9) is Java's built-in Service Provider Interface (SPI) mechanism. It discovers and loads implementations of an interface at runtime without hardcoding them.
ServiceLoader = a universal power adapter standard. Your device (service consumer) uses a standard plug shape (interface). Any country's outlet (provider) that matches the standard works. New outlets can be added without changing the device — just plug in.
Key Concepts
1
How it works:
1. Define a service interface: public interface PaymentProcessor { void process(Payment p); }
2. Create implementations: class StripeProcessor implements PaymentProcessor { ... }
3. Register providers: create META-INF/services/com.myapp.PaymentProcessor containing the FQCN of implementations
4. Load at runtime: ServiceLoader.load(PaymentProcessor.class)
2
With modules (Java 9):
- Provider: provides com.myapp.PaymentProcessor with com.stripe.StripeProcessor;
- Consumer: uses com.myapp.PaymentProcessor;
3
JDK uses SPI extensively:
- JDBC drivers: DriverManager uses ServiceLoader to find drivers
- java.util.logging: custom LogManager via SPI
- Charset providers: custom character encodings
- java.nio.file.spi: custom FileSystemProvider
4
ServiceLoader is lazy: implementations are instantiated on demand as you iterate. It uses the thread's context classloader by default.