Unlocking Java, Dubbo, and Spring SPI: A Deep Dive into Service Provider Interfaces

This article explains the principles and implementations of Java's built‑in SPI, Dubbo's enhanced SPI, and Spring's SPI mechanisms, compares their designs, walks through concrete code examples, and shows how they can be applied for dynamic extension in real projects.

vivo Internet Technology
vivo Internet Technology
vivo Internet Technology
Unlocking Java, Dubbo, and Spring SPI: A Deep Dive into Service Provider Interfaces

Overview

The Service Provider Interface (SPI) is a built‑in Java mechanism that discovers service implementations at runtime, improving framework extensibility. The article first introduces Java SPI, then examines its use in Dubbo, and finally analyzes Spring's SPI implementations, highlighting similarities and differences.

Java SPI

Java SPI uses java.util.ServiceLoader to scan META-INF/services for files named after the fully‑qualified interface. Each file lists implementation class names. A simple example defines a DataBaseSPI interface, two implementations ( MysqlDataBaseSPIImpl and OracleDataBaseSPIImpl), and a configuration file placed under META-INF/services/jdk.spi.DataBaseSPI. The test class loads the implementations with ServiceLoader.load(DataBaseSPI.class) and iterates over them, producing output for both MySQL and Oracle.

Dubbo SPI

Dubbo adopts the same design idea but adds direct name‑based access and richer extension points. An @SPI ‑annotated interface becomes an extension point, and each implementation is called an extension. Configuration files can reside in three directories ( META-INF/dubbo/internal, META-INF/dubbo, META-INF/services) and are loaded by different strategy classes. The example shows a DataBaseSPI interface, two implementations, and a dubbo.spi.DataBaseSPI file that maps names ( mysql, oracle) to classes. ExtensionLoader.getExtensionLoader(DataBaseSPI.class) creates a loader, and getExtension("mysql") retrieves the named instance, producing distinct output without iteration.

Spring SPI

Spring provides two SPI mechanisms:

spring.handlers : Maps a namespace URI to a NamespaceHandler class. Custom handlers (e.g., MysqlDataBaseHandler, OracleDataBaseHandler) are defined, and a spring.handlers file links URIs to these classes. DefaultNamespaceHandlerResolver loads the mappings, instantiates handlers via reflection, and caches them for later use during XML parsing.

spring.factories : Uses a single META-INF/spring.factories file where the key is a fully‑qualified interface name and the value is a comma‑separated list of implementation class names. SpringFactoriesLoader.loadFactories() reads all spring.factories resources, parses the values, instantiates each class, and returns a list of instances. The article demonstrates this with a DataBaseSPI interface and two implementations, showing the loaded output.

Both mechanisms rely on lazy loading and reflection, but spring.handlers provides direct URI‑to‑handler mapping, while spring.factories follows the classic Java SPI pattern of iterating over implementations.

Application Practice

The author describes a lightweight sharding SDK that uses spring.factories to load custom sharding strategies at startup. By defining strategy interfaces ( ShardingStrategy, DBTableShardingStrategy) and default implementations, developers can add new strategies simply by adding them to spring.factories, and the SDK loads them via SpringFactoriesLoader.loadFactories().

Conclusion

SPI separates service contracts from implementations, enabling high extensibility. Java SPI offers a simple file‑based discovery, Dubbo enhances it with named extensions and multiple loading paths, and Spring provides two complementary approaches— spring.handlers for XML namespace handling and spring.factories for generic interface loading. Understanding these mechanisms helps developers design flexible, pluggable architectures.

Java SPI configuration file
Java SPI configuration file
Dubbo SPI extension file
Dubbo SPI extension file
Spring handlers configuration
Spring handlers configuration
Spring factories loading process
Spring factories loading process
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.

Backend DevelopmentDubbospringJava SPIservice-provider-interfaceExtension Mechanism
vivo Internet Technology
Written by

vivo Internet Technology

Sharing practical vivo Internet technology insights and salon events, plus the latest industry news and hot conferences.

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.