API:API(Application Programming Interface)表示应用程序编程接口
SPI:SPI(Service Provider Interface)表示服务提供商接口
API与SPI的关系
框架提供API及其实现,框架在实现过程中提供SPI回调机制。SPI是框架的扩展点。如果使用框架方要扩展框架,可以自己实现SPI并注入框架,于是框架使用方其实也是一个服务提供商。
spi 是 Java 提供的一套用来被第三方实现或者扩展的 API ,它可以用来启用框架扩展和替换组件。spi 机制是这样的:读取 META-INF/services/
目录下的元信息,然后 ServiceLoader 根据信息加载对应的类,你可以在自己的代码中使用这个被加载的类。要使用 Java SPI,需要遵循如下约定:
1.当服务提供者提供了接口的一种具体实现后,在 jar 包的 META-INF/services 目录下创建一个以 “接口全限定名” 命名的文件,内容为实现类的全限定名;
2.接口实现类所在的 jar 包放在主程序的 classpath 中;
3.主程序通过 java.util.ServiceLoder 动态装载实现模块,它通过扫描 META-INF/services 目录下的配置文件找到实现类的全限定名,把类加载到 JVM ;
4.SPI 的实现类必须携带一个不带参数的构造方法;
有两种方式,一种是第三方提供实现,另一种是应用自身自己提供实现。
参考https://blog.csdn.net/shuzhupeng/article/details/80488861 方法一:利用 Spring ApplicationContext获取 中 定义的接口 与实现类
// 加载驱动,项目启动时 加载 Driver 类
1.Class.forName("com.mysql.jdbc.Driver");
2.Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/demo", "root", "root");
3.Statement stmt = conn.createStatement();
4.ResultSet rs = stmt.executeQuery("select * from Stuent");
//步骤2、3、4可以看做是API的调用。而DriverManager、Conn的编写则可以看做是SPI,实现制定的接口。
1.建一个 maven 项目,定义一个接口 ( com.haoyi.spi)
2.并实现该接口( com.haoyi.spi.impl.XhHospital 、com.haoyi.spi.impl.TjHospital)
3.然后在 src/main/resources/
下建立 /META-INF/services
目录,
新增一个以接口命名的文件 ( com.haoyi.spi.HospitalService
),
内容是要应用的实现类(com.haoyi.spi.impl.TjHospital 、com.haoyi.spi.impl.XhHospital)
定义接口
package com.haoyi.spi;
public interface HospitalService {
void getSchecule();
}
实现类
package com.haoyi.spi.impl;
import com.haoyi.spi.HospitalService;
public class TjHospital implements HospitalService {
@Override
public void getSchecule() {
System.out.println("TjHospital getSchedule");
}
}
package com.haoyi.spi.impl;
import com.haoyi.spi.HospitalService;
public class XhHospital implements HospitalService {
@Override
public void getSchecule() {
System.out.println("XhHospital getSchedule");
}
}
测试方法
package com.haoyi.junit.test.spi;
import com.haoyi.spi.HospitalService;
import sun.misc.Service;
import java.util.Iterator;
import java.util.ServiceLoader;
public class Test {
public static void main(String[] args) {
Iterator providers = Service.providers(HospitalService.class);
ServiceLoader load = ServiceLoader.load(HospitalService.class);
while(providers.hasNext()){
HospitalService service = providers.next();
service.getSchecule();
}
System.out.println("---------------------------------");
Iterator iterator = load.iterator();
while (iterator.hasNext()){
HospitalService service = iterator.next();
service.getSchecule();
}
}
}
输出:
TjHospital getSchedule
XhHospital getSchedule
---------------------------------
TjHospital getSchedule
XhHospital getSchedule