One, SPI mechanism
Here is a concept of SPI, SPI English for service Provider interface is literally understood as the service provider interface, as in the name of the SPI to understand the SPI is the service provider interface My definition of SPI: an interface that is available to developers of service providers and extended framework functions.
In our daily development is to abstract the problem into the API and then provide the implementation of various APIs, the implementation of these APIs are encapsulated with our jar or framework, although when we want to provide a new implementation of the API can not modify the original code can only implement the API to provide a new implementation of the API, But we're still building a new jar or framework (although it's possible to scan a directory for a new implementation of the API's loaded APIs, but this is not a Java mechanism, it's just the Hack method), and with the Java SPI mechanism we can provide a new implementation for the API without modifying the jar package or framework.
Many frameworks use Java's SPI mechanism, such as Java.sql.Driver's SPI implementation (MySQL driver, Oracle driver, etc.), common-logging log interface Implementation, Dubbo extension implementation, and so on.
SPI the Convention of the Mechanism:
1) Create a file in the meta-inf/services/directory named after the interface fully qualified name the full qualified name of the API-specific implementation class for the file content
2) using the Serviceloader class to dynamically load the implementation class in the Meta-inf
3) If the SPI implementation class is a jar, it needs to be placed in the main program Classpath
4) API specific implementation class must have a constructor without parameters
SPI mechanism structure diagram
Second, SPI Mechanism Example
Instance structure diagram
ioperation Interface:
12345678 |
/**   * Created by LX on 2015/3/8.   */ public interface ioperation {      Code class= "Java keyword" >public int operation ( int numbera, int numberb); |
Plusoperationimpl implementation:
123456789101112 |
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;
}
}
|
SPI implementation class for the interface: Divisionoperationimpl
123456789101112 |
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/services files in the directory:
File name: co.solinx.demo.api.IOperation, Content: Co.solinx.demo.spi.DivisionOperationImpl
Main class:
1234567891011121314151617181920212223242526272829 |
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
));
}
}
}
|
Operation Result:
if the SPI implementing packaging as a jar need to put the jar put it in Classpath . directory, the SPI jar package Run Result:
The SPI mechanism of Java with a simple example