SPI is short for Service Provider Interface. This article explains what SPI does and how to use it. SPI is a very useful thing.

What is the SPI

SPI primarily addresses the coupling problem. We know that interface oriented programming is a good way of programming, that there are some specifications defined in Java, some interfaces, and the implementation of an interface can be implemented by a third party, as long as they follow the interface implementation specification. For example, we are familiar with JDBC is such.

The common reference to SPI is the ClassLoader. We know that there are three class loaders in the JVM: BootstrapClassLoader, ExtClassLoader, and AppClassLoader. It adopts parental delegation mode. The JDK also recommends using this approach when loading classes. But if SPI uses this approach, it will cause problems with not finding classes.

Using JDBC as a class, a brief explanation of the problems with parental delegation:

  • First, we know that the JDBC interface is the core Java package, and in rt.jar, this JAR is loaded by BootstrapClassLoadre.
  • Second, the SPI loading rule is to find the corresponding implementation class based on the meta-INF services file in the JAR package. In meta-INF services, a file is defined whose filename is the full type of the interface class and whose content is the full class name of the implementation class.
  • Again, the implementation Class is loaded from DriverManager using class.forname, which uses the current Class loader. The current Class loader is BootstrapClassLoader. We know that BootstrapClassLoader loads rT.jar by default. Obviously the third-party implementation is not in rt.jar
  • Finally, how to solve this problem? SPI uses ContextClassLoader to load third-party implementation classes, This prevents the parent classloader-bootstrapClassLoader from loading classes that should be loaded by the child classloader-appClassLoader. ContextClassLoader is designed to solve this problem.

How to use SPI.

  • First implement an interface

  • Next, get an interface implementation class

  • SPI needs to create a file under services in the META-INF jar package from which SPI finds the implementation classes.

File name: full class name of the interface File content: full class name of the implementation classCopy the code
  • Finally, through ServiceLoader to load, interface oriented programming, to achieve the purpose of decoupling.
Hello hello = null;
ServiceLoader<Hello> serviceLoader = ServiceLoader.load(Hello.class);
Iterator<Hello> iter = serviceLoader.iterator();
if (iter.hasNext()) {
    hello = iter.next();
}
System.out.println(hello.say());
Copy the code

conclusion

As you can see from the above, SPI should have a lot of uses, defining the interface specification, and the implementation of the interface can be implemented by different third parties, and in the process of programming, you can also program for the interface, which is very elegant to write.