Master Java SPI: From JDK to Dubbo & Spring – Extend Your Apps Easily

This article explains the concept and usage of Service Provider Interface (SPI) in Java, demonstrating how JDK’s ServiceLoader, Dubbo’s enhanced SPI, and Spring’s SPI mechanisms enable flexible extension of logging frameworks and other components, while comparing their features, configuration files, and limitations.

Java Backend Technology
Java Backend Technology
Java Backend Technology
Master Java SPI: From JDK to Dubbo & Spring – Extend Your Apps Easily

SPI (Service Provider Interface) is a service discovery mechanism that registers fully qualified class names in configuration files, allowing dynamic replacement of implementations at runtime.

Example: a simple logging framework "super‑logger" defines an interface SuperLoggerConfiguration and a default XML implementation XMLConfiguration. Initially, LoggerFactory directly creates XMLConfiguration, which limits extensibility.

By placing a file

META-INF/services/com.github.kongwu.spisamples.SuperLoggerConfiguration

containing the implementation class name, Java’s ServiceLoader can load all implementations. The code to load them looks like:

ServiceLoader<SuperLoggerConfiguration> serviceLoader = ServiceLoader.load(SuperLoggerConfiguration.class);
Iterator<SuperLoggerConfiguration> iterator = serviceLoader.iterator();
SuperLoggerConfiguration configuration;
while (iterator.hasNext()) {
    // load and initialize implementation
    configuration = iterator.next();
}
configuration.configure(configFile);

The LoggerFactory static block is rewritten to use this SPI loading, enabling users to add a YAMLConfiguration implementation without modifying the factory code.

However, JDK SPI selects implementations based on class‑path order; the last loaded implementation is used, which can be unpredictable.

Dubbo SPI

Dubbo enhances SPI by using key‑value pairs in META-INF/dubbo files, allowing each implementation to have an alias. Interfaces are annotated with @SPI, and implementations can be retrieved by name via ExtensionLoader:

@SPI
public interface Robot {
    void sayHello();
}
public class OptimusPrime implements Robot {
    @Override public void sayHello() { System.out.println("Hello, I am Optimus Prime."); }
}
public class Bumblebee implements Robot {
    @Override public void sayHello() { System.out.println("Hello, I am Bumblebee."); }
}
ExtensionLoader<Robot> loader = ExtensionLoader.getExtensionLoader(Robot.class);
Robot optimus = loader.getExtension("optimusPrime");
optimus.sayHello();
Robot bumble = loader.getExtension("bumblebee");
bumble.sayHello();

Dubbo also supports a default implementation via the value attribute of @SPI, and an adaptive mechanism for more flexible loading.

Spring SPI

Spring uses a single file META-INF/spring.factories where each interface maps to a comma‑separated list of implementation classes. For example, loading all LoggingSystemFactory implementations:

List<LoggingSystemFactory> factories = SpringFactoriesLoader.loadFactories(
    LoggingSystemFactory.class, classLoader);

Typical content of spring.factories includes entries for logging systems, property source loaders, and other boot components. Adding a custom implementation only requires adding a new line for the desired interface, without copying the entire file.

Spring’s SPI loads files in class‑path order, giving priority to user‑defined factories, which makes it easy to override default behavior.

Comparison

JDK SPI uses separate files per extension point, provides only ordered loading, and has no alias support. Dubbo SPI adds aliasing, internal vs external priority, and richer documentation. Spring SPI consolidates all extensions into one file, relies on class‑path order, and enjoys IDE support.

Overall, JDK SPI is the simplest but least flexible, Dubbo SPI offers the most features but is tied to Dubbo, and Spring SPI strikes a balance with straightforward configuration and good tooling.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

javaDubbospringSPIServiceLoader
Java Backend Technology
Written by

Java Backend Technology

Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.