Comparing Java, Spring, and Dubbo SPI Mechanisms

Crazy Flash Sale Season:199Yuan Flash Sale Original Price 699

Microservice Registration Center Source Code Analysis and Architecture Design Course”

Today11 AM,only 66 sets, first come first servedComparing Java, Spring, and Dubbo SPI MechanismsSource: https://c1n.cn/my8R6The SPI mechanism is applied in many places in our projects and is commonly used in many frameworks, although many people are not aware of it.For example, why can we directly connect to the MySQL database just by introducing the mysql-connector jar package in our project?

Comparing Java, Spring, and Dubbo SPI Mechanisms

This article will introduce SPI and discuss the SPI mechanisms in Java, Spring, and Dubbo.

SPI

SPI (Service Provider Interface) is a service discovery mechanism.The essence of SPI is to configure the fully qualified names of the implementation classes of the interfaces in a file, which are read by the service loader to load the corresponding implementation classes of the interfaces. This allows us to obtain the implementation classes of the interfaces at runtime.With this feature, we can easily provide extension functionality for programs through the SPI mechanism.

Java SPI

Java SPI mechanism:

Comparing Java, Spring, and Dubbo SPI Mechanisms

Java SPI is a dynamic loading mechanism implemented by combining interface-based programming, the strategy pattern, and configuration files.Design an interface, write the implementation classes in the configuration file, and the service discovers and loads the implementation classes by reading the configuration file.Configuration file path: META-INF/services/ under the classpathConfiguration file name: fully qualified name of the interfaceConfiguration file content: fully qualified names of the implementation classes of the interfaceExample of application:

1. Custom interface

// Interface
public interface Superman {
    void introduce();
}

// Implementation class 1
public class IronMan implements Superman{
    @Override
    public void introduce() {
        System.out.println("I am Iron Man!");
    }
}
// Implementation class 2
public class CaptainAmerica implements Superman {
    @Override
    public void introduce() {
        System.out.println("I am Captain America!");
    }
}

Configuration file:

Comparing Java, Spring, and Dubbo SPI Mechanisms

Testing:

public static void main(String[] args) {
    ServiceLoader<Superman> serviceLoader = ServiceLoader.load(Superman.class);
    System.out.println("Java SPI:");
    serviceLoader.forEach(Superman::introduce);
}

Output:

Comparing Java, Spring, and Dubbo SPI Mechanisms

2. java.sql.Driver interface

MySQL implementation:Comparing Java, Spring, and Dubbo SPI Mechanisms

By now, you should know the answer to the initial question: the mysql-connector jar package implements the java Driver interface through SPI, allowing our service to obtain the MySQL driver class at runtime and thus connect to MySQL.

Java SPI principle:

The implementation of Java SPI is in the ServiceLoader class:

Here is a snippet of code; interested readers can read it themselves.

Comparing Java, Spring, and Dubbo SPI MechanismsGet configuration files under the prefix (including jar packages):Comparing Java, Spring, and Dubbo SPI Mechanisms

Java SPI Summary:

Java SPI mechanism: a mechanism for discovering/finding service implementations for a certain interface.

Advantages:

Core idea:Decoupling, allowing the logic of assembling third-party service modules to be separated from the business code of the caller.Can be used or extended according to actual business needs.

Disadvantages:1. The way to obtain the implementation class of the interface is not flexible; serviceLoader can only iterate to obtain it and cannot get a specific implementation class based on parameters.

2. Resource wastage

serviceLoader can only obtain, load, and instantiate all implementation classes of the interface through iteration. If certain implementation classes are not needed, they are still loaded and instantiated, causing waste.

Spring SPI

Similar to JDK SPI, the advantage over Java’s SPI is:Spring SPI specifies the configuration file as META-INF/spring.factories under the classpath, where all extension point configurations are placed in one file.The configuration file content is key-value type, where the key is the fully qualified name of the interface, and the value is the fully qualified name of the implementation class, which can have multiple entries.Example of spring.factories file:

Comparing Java, Spring, and Dubbo SPI Mechanisms

Example of application:

Using Dubbo as an example:

Why can we directly use Dubbo services just by introducing the dubbo jar package and configuring registry and provider in application.yml?

Comparing Java, Spring, and Dubbo SPI Mechanisms

There’s no such thing as a peaceful life; it’s just that someone is carrying the weight for you. The “weight-bearing person” is the “dubbo-spring-boot-starter”. It actually uses Spring SPI:

Comparing Java, Spring, and Dubbo SPI Mechanisms

Taking the implementation class DubboAutoConfiguration of EnableAutoConfiguration as an example:

During the startup process of Spring Boot, during the step SpringFactoriesLoader.loadFactoryNames(type, classLoader), all implementation classes of EnableAutoConfiguration will be loaded, parsed, and initialized.

When instantiating the implementation class of EnableAutoConfiguration, the specific logic in the dubboAutoConfiguration implementation class will be executed, starting and registering the Dubbo service in the Spring container.

Approximate implementation of DubboAutoConfiguration:

Read the configuration item values from the configuration file (configuration item: DubboConfigConfiguration) to generate multiple configuration beans, scan the classes annotated with @Service and @Reference in Dubbo, and generate the corresponding beans.

In fact, many third-party dependency packages we use have also utilized Spring SPI, such as Dubbo, MyBatis, Redisson, and so on.Comparing Java, Spring, and Dubbo SPI Mechanisms

Dubbo SPI

Dubbo’s Filter, Protocol, Cluster, LoadBalance, etc., are all loaded through SPI for extension.

Characteristics:

1. Dubbo SPI sets a separate file for each extension point (interface), named after the fully qualified name of the interface.For example: org.apache.dubbo.rpc.Filter, org.apache.dubbo.rpc.Protocol, org.apache.dubbo.rpc.cluster.LoadBalance, etc.

Example of Dubbo SPI configuration file:

Comparing Java, Spring, and Dubbo SPI Mechanisms

2. Supports the concept of “alias”; you can obtain a specific implementation of the extension point through its alias.The configuration file content is key-value type, where the key is the alias and the value is the fully qualified name of the implementation class.If you only use a specified filter, other filters will not be instantiated.

Comparing Java, Spring, and Dubbo SPI Mechanisms

3. Supports internal dependency injection in Dubbo

Dubbo IOC

Dependency injection is performed through setter methods. Dubbo first obtains all methods of the instance through reflection, then iterates through the method list to check if the method names have setter characteristics. If so, it obtains the dependency object through ObjectFactory and finally calls the setter method through reflection to set the dependency into the target object.

Implementation:The implementation of Dubbo SPI is in the ExtensionLoader class.Taking the example of obtaining all Dubbo Filters:1. First, obtain the ExtensionLoader of the Filter

ExtensionLoader.getExtensionLoader(Filter.class)

2. The ExtensionLoader loads all extension classes from the configuration file

Comparing Java, Spring, and Dubbo SPI Mechanisms

Load configuration files from the following directories in the project and jar packages:

Comparing Java, Spring, and Dubbo SPI Mechanisms

The configuration file is named after the fully qualified name of the interface.

3. When reading the configuration file, the key-value pairs are confirmed based on the ‘=’ delimiter.

Thus, a mapping relationship table from “configuration item name” to “configuration class” is obtained.

4. Caching is used in multiple places to improve performance.

Cache extension class corresponding to ExtensionLoader, etc.

After obtaining the alias – fully qualified name of the implementation class, you can directly obtain the specified extension class through the alias.

Comparison of Java, Spring, and Dubbo SPI

Comparing Java, Spring, and Dubbo SPI Mechanisms


-------------  END  -------------
Scan to get 600+ pages of original high-quality articles by Teacher Shi Shan in PDF format

Collection of Original Technical Articles

Click to see what you like best


Leave a Comment