参考资料:
简介:
概念
JDK SPI 是一种基于 ServiceLoader 的接口实现发现机制,它通过扫描 Jar 包中 META-INF/services 目录下的配置文件,动态加载接口实现类。
具体实现方式
JDK提供的Service类的providers方法或者ServiceLoader类的load方法,根据指定接口,遍历并发现,加载的JAR包中,resources目录下的META-INF/services文件夹中该接口的实现类信息;

在该文件夹下,存在文件,名称为接口的全限定名,内容为该接口实现类的全限定名,可以是多个;

在根据接口全限定名找到该接口的多个实现类全限定名后,将实现类加载到JVM中,可以使用迭代器等方式,遍历并执行接口的多种实现方式。

应用
该技术特点是,强解耦,热插拔的特点,广泛应用于java项目的JDBC连接等;
如java项目在数据库连接方面的处理:
首先,JDK会内置JDBC接口规范,并在JDK启动时,会扫描加载的JAR包中,是否有该接口的实现,如果有则逐个建立连接(如:MySQL、oracle等)。
具体搭建方式:
详情见参考demo
首先需要一个多model的项目

在第一个model中创建接口
java
package org.example;
public interface JdbcInstall {
public String install();
}
执行 mvn -install命令,并将依赖引入到第二个项目中
bash
<dependency>
<groupId>org.example</groupId>
<artifactId>java-jdbc-interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>

然后在第二个项目中编写该接口的实现类
java
package org.example.jdbcimpl;
import org.example.JdbcInstall;
public class JdbcImpl_01 implements JdbcInstall {
@Override
public String install() {
return "MySQL驱动安装成功!!!";
}
}
java
package org.example.jdbcimpl;
import org.example.JdbcInstall;
public class JdbcImpl_02 implements JdbcInstall {
@Override
public String install() {
return "Oracle驱动安装成功!!!";
}
}
java
package org.example.jdbcimpl;
import org.example.JdbcInstall;
public class JdbcImpl_03 implements JdbcInstall {
@Override
public String install() {
return "SQL server驱动安装成功!!!";
}
}
并创建resources/META-INF\services目录,添加文件,文件名为接口的全限定名,内容为实现类的全限定名
java
org.example.jdbcimpl.JdbcImpl_01
org.example.jdbcimpl.JdbcImpl_02
org.example.jdbcimpl.JdbcImpl_03
执行 mvn -install命令,并将依赖引入到第三个项目中

java
<dependency>
<groupId>org.example</groupId>
<artifactId>java-jdbcimpl-use</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
并且编写代码,使用该接口
bash
package org.example;
import sun.misc.Service;
import java.util.Iterator;
import java.util.ServiceLoader;
public class JbdcUse {
public static void main(String[] args) {
Iterator<JdbcInstall> providers = Service.providers(JdbcInstall.class);
ServiceLoader<JdbcInstall> load = ServiceLoader.load(JdbcInstall.class);
while(providers.hasNext()) {
JdbcInstall ser = providers.next();
System.out.println(ser.install());
}
System.out.println("--------------------------------");
Iterator<JdbcInstall> iterator = load.iterator();
while(iterator.hasNext()) {
JdbcInstall ser = iterator.next();
System.out.println(ser.install());
}
}
}