Understanding and Comparing Java, Spring, and Dubbo SPI Mechanisms
This article explains the concept of Service Provider Interface (SPI), demonstrates how Java's ServiceLoader, Spring's SpringFactoriesLoader, and Dubbo's ExtensionLoader implement SPI, compares their configurations and capabilities, and discusses advanced features such as adaptive extensions, IOC/AOP integration, wrappers, and auto‑activation.
SPI (Service Provider Interface) is a design pattern that decouples interfaces from their implementations, allowing dynamic discovery and replacement via configuration files, which enhances framework extensibility.
Java SPI – ServiceLoader
Java provides a simple SPI implementation through ServiceLoader . Implementations must place a file named with the fully‑qualified interface name under META-INF/services/ , containing the fully‑qualified class names of the implementations.
Demo:
public interface LoadBalance {}
public class RandomLoadBalance implements LoadBalance {}
public class ServiceLoaderDemo {
public static void main(String[] args) {
ServiceLoader
loader = ServiceLoader.load(LoadBalance.class);
for (LoadBalance lb : loader) {
System.out.println("Loaded LoadBalance: " + lb);
}
}
}The loader reads the service file, uses reflection to instantiate each implementation, and iterates over them. Drawbacks include eager instantiation of all implementations and lack of selective loading.
Spring SPI – SpringFactoriesLoader
Spring uses SpringFactoriesLoader with a single spring.factories file placed under META-INF/ . The file contains key‑value pairs where keys are interface names and values are comma‑separated implementation class names.
Demo:
public interface LoadBalance {}
public class RandomLoadBalance implements LoadBalance {}
public class SpringFactoriesLoaderDemo {
public static void main(String[] args) {
List
lbs = SpringFactoriesLoader.loadFactories(LoadBalance.class, MyEnableAutoConfiguration.class.getClassLoader());
for (LoadBalance lb : lbs) {
System.out.println("Loaded LoadBalance: " + lb);
}
}
}Spring’s SPI is heavily used in Spring Boot for auto‑configuration and other extension points.
Dubbo SPI – ExtensionLoader
Dubbo extends the SPI concept with ExtensionLoader . Interfaces must be annotated with @SPI , and configuration files can reside in several META-INF directories. Files use key‑value pairs where the key is a short name and the value is the implementation class.
Demo:
@SPI
public interface LoadBalance {}
// META-INF/services/com.example.LoadBalance
random=com.example.RandomLoadBalance
public class ExtensionLoaderDemo {
public static void main(String[] args) {
ExtensionLoader
loader = ExtensionLoader.getExtensionLoader(LoadBalance.class);
LoadBalance lb = loader.getExtension("random");
System.out.println("Loaded LoadBalance: " + lb);
}
}Dubbo adds advanced features:
Adaptive extensions : a single adaptive class can delegate to specific implementations based on runtime parameters via getAdaptiveExtension() .
IOC/AOP integration : Dubbo performs setter‑based injection and supports wrapper classes that act as static proxies.
Wrapper classes : classes with a constructor that accepts the interface type are automatically wrapped to form a responsibility chain.
Auto‑activation : implementations annotated with @Activate are selected automatically based on criteria, commonly used for filter chains.
Comparison
Java’s SPI is straightforward but limited to loading all implementations. Spring simplifies configuration with a single file and leverages its own IOC/AOP mechanisms, but still lacks selective loading. Dubbo’s SPI is the most feature‑rich, providing adaptive loading, wrapper chaining, auto‑activation, and deeper integration with its own lightweight IOC/AOP framework.
Conclusion
All three SPI mechanisms share the core idea of reading configuration files via I/O streams and using reflection to instantiate implementations. Java offers the simplest form, Spring builds on it with its ecosystem, and Dubbo extends it to meet complex framework requirements.
Code Ape Tech Column
Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.