All 15 Class Loading & Bytecode Verification questions
More in Class Loading & Bytecode Verification
Advertisement
Java › Class Loading & Bytecode Verification

How does the ServiceLoader mechanism (java.util.ServiceLoader) provide a standardized way to discover and load implementations at runtime without hardcoding class names, and how does it relate to class loading?

Intermediate

Answer

ServiceLoader implements the Service Provider Interface (SPI) pattern: a service interface is defined, implementations are registered by listing their fully-qualified class name in a META-INF/services/ file named after the interface (or via a `provides...with` declaration in module-info.java under JPMS), and ServiceLoader.load(MyService.class) discovers and instantiates all registered implementations found on the classpath/module path at runtime -- this relies on the underlying class loading mechanism to actually resolve and instantiate each discovered implementation class, providing a clean decoupling between an interface's consumers and its concrete implementations.
// META-INF/services/com.example.PaymentProcessor (file content, one implementation class name per line)
// com.example.impl.StripeProcessor
// com.example.impl.PayPalProcessor

ServiceLoader<PaymentProcessor> loader = ServiceLoader.load(PaymentProcessor.class);
for (PaymentProcessor processor : loader) {
    System.out.println("Found processor: " + processor.getClass().getName());
}
Real-world example The JDBC 4.0+ driver auto-registration mechanism uses ServiceLoader internally to automatically discover and register any JDBC driver JAR present on the classpath, eliminating the need for the older explicit Class.forName() driver-registration call entirely.

Common follow-ups: How does ServiceLoader discovery differ between the classpath and JPMS module path?;What are the performance implications of ServiceLoader scanning for implementations at startup?