Java SPI mechanism and simple example, callback PI Mechanism
I. SPIMechanism
Here we will first describe the concept of SPI. In English, a single SPI Service Provider Interface can be literally understood as a Service Provider Interface, just as a Service Provider Interface can be understood from the SPI name; my SPI definition: interfaces used by developers who provide services with vendor and extended framework functions.
During our daily development, we abstract the problem into an Api and then provide the implementation of various APIs, the implementation of these Apis is encapsulated with our Jar or framework. Although when we want to provide a new Api implementation, we can provide a new Api implementation without modifying the original code., but we still generate a new Jar or framework (although we can scan a directory in the code to load the new Implementation of the Api, but this is not a Java mechanism, but only the hack method ), with the Java SPI mechanism, we can provide new implementation for the Api without modifying the Jar package or framework.
Many frameworks use the java SPI mechanism, such as java. SQL. driver SPI implementation (mysql Driver, oracle Driver, etc.), common-logging log interface implementation, dubbo extension implementation, and other frameworks;
SPIMechanism conventions:
1) create a file in the META-INF/services/directory named after interface full qualified name. The file content is the full qualified name of the specific implementation class of the Api
2) use ServiceLoader class to dynamically load the implementation class in META-INF
3) if the SPI implementation class is Jar, it must be placed in the main program classPath.
4) the Api implementation class must have a constructor without parameters.
SPI Mechanism structure
Ii. SPIMechanism example
Instance Structure
IOperationInterface:
/** * Created by LX on 2015/3/8. */public interface IOperation { public int operation(int numberA, int numberB);}
PlusOperationImplImplementation:
import co.solinx.demo.api.IOperation;/** * Created by LX on 2015/3/8. */public class PlusOperationImpl implements IOperation { @Override public int operation(int numberA, int numberB) { return numberA + numberB; }}
SPIInterface implementation class: DivisionOperationImpl
import co.solinx.demo.api.IOperation;/** * Created by LX on 2015/3/8. */public class DivisionOperationImpl implements IOperation { @Override public int operation(int numberA, int numberB) { return numberA / numberB; }}
META-INF/ServicesFiles in the directory:
File Name: co. solinx. demo. api. IOperation, content: co. solinx. demo. spi. DivisionOperationImpl
MainClass:
import co.solinx.demo.api.IOperation;import co.solinx.demo.impl.PlusOperationImpl;import co.solinx.demo.spi.DivisionOperationImpl;import java.util.Iterator;import java.util.ServiceLoader;/** * Created by LX on 2015/3/8. */public class main { public static void main(String[] args) { IOperation plus = new PlusOperationImpl(); IOperation division = new DivisionOperationImpl(); System.out.println(plus.operation(5, 3)); System.out.println(division.operation(9, 3)); ServiceLoader<IOperation> operations = ServiceLoader.load(IOperation.class); Iterator<IOperation> operationIterator = operations.iterator(); System.out.println("classPath:"+System.getProperty("java.class.path")); while (operationIterator.hasNext()) { IOperation operation = operationIterator.next(); System.out.println(operation.operation(6, 3)); } }}
Running result:
For exampleImplement package as jarJarPut it in classpathDirectory, SPI jarPackage running result:
First Article address: Solinx
Http://www.solinx.co/archives/142