Author: Waste elder martial brother
Source: www.cnblogs.com/cjsblog/p/14346766.html
SPI (Service Provider Interface) is a service provider discovery mechanism built into JDK. The essence is to configure the fully qualified name of the interface implementation class in the file, and the service loader reads the configuration file and loads the implementation class. In this way, you can dynamically replace the implementation class for the interface at run time.
In Java, SPI is used to design plug-ins for service providers. The mechanism of dynamic loading based on policy pattern. We only define one interface in the program, and the specific implementation is handed over to different service providers; When the program starts, read the configuration file, and the configuration determines which implementation to call. Many components are implemented in this way, such as log and database access. The most commonly used is JDBC driver.
1,Java SPI
Core class: Java util. ServiceLoader
A service is a well-known set of interfaces and (usually Abstract) classes. A service provider is a specific implementation of a service. Classes in providers typically implement interfaces and subclass classes defined in the service itself. Service providers can be installed in the implementation of the Java platform in the form of extensions, that is, jar files placed in any common extension directory. Providers can also be provided by adding them to the application's classpath or other platform specific methods.
Identify the service provider by placing a provider configuration file in the resource directory META-INF/services. The file name is the fully qualified binary name of the service type. This file contains a list of fully qualified binary names of specific provider classes, one per line. Spaces and tabs around each name and blank lines are ignored. The comment character is' # '; In each line, all characters after the first comment character are ignored. The file must be encoded in UTF-8.
According to the above method, let's write an example to try
First, define an interface Car
package org.example; public interface Car { void run(); }
Two implementation classes
ToyotaCar.java
package org.example; public class ToyotaCar implements Car { @Override public void run() { System.out.println("Toyota"); } }
HondaCar.java
package org.example; public class HondaCar implements Car { @Override public void run() { System.out.println("Honda"); } }
Create a file called org. Org under META-INF/services example. Car's text file
org.example.ToyotaCar org.example.HondaCar
Finally, write a test class to run and see the effect
package org.example; import java.util.ServiceLoader; public class App { public static void main( String[] args ) { ServiceLoader<Car> serviceLoader = ServiceLoader.load(Car.class); serviceLoader.forEach(x->x.run()); } }
Follow the code of ServiceLoader to see how to find the service implementation
Load with the classloader of the current thread
Interfaces and class loaders are available, and everything is ready, only due to Dongfeng
Shortcomings of Java SPI:
- Cannot load on demand. When loading extension points, Java SPI will load all available extension points at one time. Many of them are unnecessary and will waste system resources
- The method of obtaining an implementation class is not flexible enough. It can only be obtained in the form of Iterator, and the corresponding implementation class cannot be obtained according to a parameter
- AOP and IOC are not supported
- If the extension point fails to load, the caller will report an error, which makes it difficult to trace
2,Dubbo SPI
Dubbo re implements a set of more powerful SPI mechanism, supports AOP and dependency injection, uses cache to improve the performance of loading implementation classes, and supports flexible acquisition of implementation classes.
<dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>2.7.8</version> </dependency>
Core category: org.org apache. dubbo. common. extension. ExtensionLoader
Let's first understand the @ SPI annotation, which is used to mark that the interface is an extensible interface
Modify the previous example and add @ SPI annotation on the Car interface
package org.example; import org.apache.dubbo.common.extension.SPI; @SPI public interface Car { void run(); }
The two implementation classes remain unchanged
Create a file called org. Org in the META-INF/dubbo directory example. The text file of car is as follows (in the form of key value pair):
toyota=org.example.ToyotaCar honda=org.example.HondaCar
Write test class:
package org.example; import org.apache.dubbo.common.extension.ExtensionLoader; import java.util.ServiceLoader; public class App { public static void main( String[] args ) { // Java SPI ServiceLoader<Car> serviceLoader = ServiceLoader.load(Car.class); serviceLoader.forEach(x->x.run()); // Dubbo SPI ExtensionLoader<Car> extensionLoader = ExtensionLoader.getExtensionLoader(Car.class); Car car = extensionLoader.getExtension("honda"); car.run(); } }
Let's follow the code
If there is in the cache Map, it will be returned directly. If not, it will be put in after loading
What is the loading strategy?
I understand a little here and see the familiar serviceload Load(), isn't this the Java SPI just mentioned
Go back to the previous place, arrange the policies in order, and traverse all the policies in turn to load. Is to find the specified files in those three directories and read the contents
It's the same as the previous ServiceLoader
If you encounter @ Adaptive annotation, it will be cached
Finally, we will pay attention to the official account Java technology stack and reply in the background: interview can get my Java, Dubbo series interview questions and answers, which are very complete.
Recent hot article recommendations:
1.1000 + Java interview questions and answers (2021 latest version)
2.Finally got the IntelliJ IDEA activation code through the open source project. It's really fragrant!
3.Ali Mock tools are officially open source and kill all Mock tools on the market!
4.Spring Cloud 2020.0.0 is officially released, a new and subversive version!
5.Java development manual (Songshan version) is the latest release. Download it quickly!
Feel good, don't forget to like + forward!