preface

Recently I read Dubbo source code. Scalability is one of the features that distinguishes Dubbo from other RPC frameworks, and the scalability of Dubbo is based on SPI. To understand what makes SPI unique, take a closer look. This article will briefly record some experiments, and write some demos for Java SPI and Dubbo SPI respectively, so as to have a perceptual understanding of SPI mechanism.

SPI

  • Java SPI: Service Provider Interface There are multiple implementations of an Interface. You can configure which implementation to use.
  • Dubbo SPI: Enhanced Version of the Java SPI, but not implemented based on the Java SPI. Instead, Dubbo has rewritten the functionality of the Java SPI itself, adding support for extension points IOC and AOP.

Java SPI Demo

The Demo is from the official Dubbo documentation website

// Define one interface and multiple implementations
public interface Robot {
    void sayHello(a);
}

// Bumblebee implementation
public class Bumblebee implements Robot{
    @Override
    public void sayHello(a) {
        System.out.println("Hello, I am Bumblebee"); }}// Optimus Prime achieved
public class OptimusPrime implements Robot{
    @Override
    public void sayHello(a) {
        System.out.println("hello, I am Optimus Prime."); }}// In the resource/ meta-INF /services/ directory, define an SPI file for the Robot interfaceThe resource/meta-inf/services/com QPM. Learn. Spi. The Robot file contents: com. The QPM. Learn. Spi. OptimusPrime com. QPM. Learn. Spi. The Bumblebee// Test case
public class RobotTest extends TestCase {
    public void testSayHello(a) {
        ServiceLoader<Robot> serviceLoader = ServiceLoader.load(Robot.class);
        System.out.println("Java SPI");
        serviceLoader.forEach(Robot::sayHello);
    }
}

console OUPUT:
Java SPI
hello, I am Optimus Prime.
Hello, I am Bumblebee
Copy the code

This is a very simple example, and the above example looks very easy to implement if you use the Spring IOC container. But SPI doesn’t come from any framework; it comes with the Java language.

SPI (Service Provider Interface) is a built-in Service discovery mechanism in JDK. SPI is a mechanism for dynamic substitution discovery. For example, if you have an interface and you want to dynamically add an implementation to it at runtime, you just need to add an implementation. The java.sql.Driver interface is one that we often encounter. Different vendors can implement the same interface differently. Mysql and PostgresQL have different implementations for users, and Java’s SPI mechanism can find service implementations for an interface. (Java SPI mechanism details)

The SPI mechanism comes from the same idea: the open closed principle, open for extension, closed for modification. For a particular program, such as Java’s java.sql.Driver, which is an interface, the Driver implementation of Mysql is loaded by the program through the SPI mechanism. It is not hard to imagine that other Driver implementations can also rely on the SPI mechanism.

Dubbo SPI

Dubbo SPI is an enhanced version of Java SPI, but Dubbo itself does not use Java SPI. In other words, Dubbo itself implements a set of functionality that is almost identical to SPI, using almost the same steps as Java SPI, which in short, is

  • Defines the interface
  • Write the implementation
  • File configuration which implementation to use

But Dubbo SPI itself has made some enhancements and rule changes:

  • The configuration directory location is different from the Java SPI. The definition of Dubbo configuration comes from: meta-INF/Dubbo
  • Dubbo has functionality similar to IOC and AOP

Dubbo SPI Demo

// Define one interface and multiple implementations
@SPI  // import org.apache.dubbo.common.extension.SPI; Dubbo's SPI is implemented with annotations
public interface Robot {
    void sayHello(a);
}

// Bumblebee implementation
public class Bumblebee implements Robot{
    @Override
    public void sayHello(a) {
        System.out.println("Hello, I am Bumblebee"); }}// Optimus Prime achieved
public class OptimusPrime implements Robot{
    @Override
    public void sayHello(a) {
        System.out.println("hello, I am Optimus Prime."); }}// In the resource/ meta-INF /dubbo/ directory, define an SPI file for the Robot interfaceThe resource/meta-inf/dubbo/com. The QPM. Dubbo. Test. The spi. Robot file content, Compared to Java SPI Dubbo SPI is a K - V design optimusPrime = com. QPM. Dubbo. Test. The SPI. OptimusPrime bumblebee=com.qpm.dubbo.test.spi.Bumblebee// Test case
    @Test
    public void sayHello(a) throws Exception {
        System.out.println("Dubbo SPI");
        
        ExtensionLoader<Robot> extensionLoader = ExtensionLoader.getExtensionLoader(Robot.class);
        Robot optimusPrime = extensionLoader.getExtension("optimusPrime");
        optimusPrime.sayHello();
        Robot bumblebee = extensionLoader.getExtension("bumblebee");
        bumblebee.sayHello();
    }

console OUPUT:
Dubbo SPI
hello, I am Optimus Prime.
Hello, I am Bumblebee
Copy the code

Afterword.

SPI in general is a design idea, and Spring’s IOC container has always been used. To understand SPI, instead, is to step outside the Spring IOC framework and consider the ideas it references in code design. I simply think that this is an implementation of the open closed principle, which is to keep extensions open, and Dubbo defines the SPI mechanism, which is to keep extensions open.

Why not use Spring to help Dubbo implement spI-like functionality? In my opinion, Dubbo, as a stand-alone RPC product, should first join the Spring ecosystem, but not rely on Spring’s underlying framework; Secondly, Spring’s IOC and AOP are too powerful for Dubbo to some extent. Implementing SPI on your own will make Dubbo lighter and more performance controlled, ensuring Dubbo’s lightweight and high performance characteristics.

Now that you’re familiar with what Dubbo’s SPI mechanism is, after a brief reflection on why Dubbo implements its own SPI mechanism, you can read the implementation source code for Dubbo SPI and how Dubbo maintains extensions for modules using its own SPI and customizes its own features.

reference

  • Java SPI mechanism in detail
  • Dubbo SPI official documentation
  • The Beauty of Geektime Design: Open and Close Principles (paid link)