JAVA SPI (Service Provider Interface)提供一种灵活的扩展机制,jdbc 的各种driver即基于此实现。下面用一个简单的例子来看一下spi的使用:
新建4个maven module
spi-test-lib ---- 接口定义(api)
spi-test-main ---- spi使用者
spi-test-service1 ---- spi提供者1
spi-test-service2 ---- spi提供者2
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.taobao.ju.felix</groupId>
<artifactId>spi-test</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>spi-test-service1</module>
<module>spi-test-service2</module>
<module>spi-test-lib</module>
<module>spi-test-main</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.taobao.ju.felix</groupId>
<artifactId>spi-test-lib</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
spi-test-lib 中定义接口:
public interface IService {
void Foo();
}
spi-test-service1, spi-test-service2 中分别实现:
public class Service1 implements IService {
@Override
public void Foo() {
System.out.println("service1 on called");
}
}
spi-test-service1,spi-test-service2 工程中定义 META-INF/services/com.taobao.ju.felix.IService 文件,各自声明自己的实现:
com.taobao.ju.felix.services.impl.Service1
spi-test-main pom.xml 中加入对 spi-test-service1-xxx.jar 和 spi-test-service2-xxx.jar 的依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spi-test</artifactId>
<groupId>com.taobao.ju.felix</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spi-test-main</artifactId>
<dependencies>
<dependency>
<groupId>com.taobao.ju.felix</groupId>
<artifactId>spi-test-lib</artifactId>
</dependency>
<dependency>
<groupId>com.taobao.ju.felix</groupId>
<artifactId>spi-test-service1</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.taobao.ju.felix</groupId>
<artifactId>spi-test-service2</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
spi-test-main 利用 ServicesLoader 进行调用:
public class MainEntry {
public static void main(String[] args) throws Exception {
ServiceLoader<IService> services = ServiceLoader.load(IService.class);
for(IService service : services) {
service.Foo();
}
}
}