Java SPI

SPI的全名为Service Provider Interface,是针对厂商或者插件的,在java.util.ServiceLoader的文档里有比较详细的介绍。

系统里抽象的各个模块,往往有很多不同的实现方案,比如jdbc模块的方案等。为了实现在模块装配的时候,能不在程序里动态指明,这就需要一种服务发现机制。

java spi就是提供这样的一个机制:为某个接口寻找服务实现的机制。

约定

服务的提供者 提供了服务接口的实现之后,在jar包的META-INF/services/目录里创建一个以服务接口命名的文件文件的内容为实现接口的全类名

如何使用

以 MySQL JDBC 驱动为例,添加 Maven 项目的依赖

1
2
3
4
5
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.13</version>
</dependency>

mysql-connector-java-5.1.13.jar 的包内结构

1
2
3
4
5
mysql-connector-java-5.1.13.jar
|-- com.mysql.jdbc
|-- META-INF
|--|-- services
|--|--|-- java.sql.Driver

代码片段

1
2
3
4
5
6
7
8
9
10
11
public class JdbcConnectTest {

public static void main(String[] args) throws ClassNotFoundException, SQLException {
ServiceLoader<Driver> sl = ServiceLoader.load(java.sql.Driver.class); // 加载 java.sql.Driver 的实现类
Iterator<Driver> iterator = sl.iterator();
if (iterator.hasNext()) {
Driver driver = iterator.next();
System.out.println(driver.getClass().getName());
}
}
}

输出

com.mysql.jdbc.Driver

使用SPI的方式连接数据库

完善以上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class JdbcConnectTest {  

public static void main(String[] args) throws ClassNotFoundException, SQLException {
ServiceLoader<Driver> sl = ServiceLoader.load(java.sql.Driver.class); // 加载 java.sql.Driver 的实现类
Iterator<Driver> iterator = sl.iterator();
if (iterator.hasNext()) {
Driver driver = iterator.next();
Properties properties = new Properties();
properties.setProperty("useUnicode", "true");
properties.setProperty("characterEncoding", "utf-8");
properties.setProperty("user", "kail");
properties.setProperty("password", "123456");
// 连接到本地的mysql库
try (Connection connect = driver.connect("jdbc:mysql:///mysql", properties)) {
try (Statement statement = connect.createStatement()) {
// 查询 db 表
try (ResultSet resultSet = statement.executeQuery("SELECT * FROM db")) {
while (resultSet.next()) {
String dbName = resultSet.getString(2);
System.out.println(dbName); // 输出库名
}
}
}
}
}
}
}

【java规范】Java spi机制浅谈

java中的SPI机制