java 原生 SPI 代码实现
2024-3-14
SPI : 全称为 Service Provider Interface, 是一种服务发现机制。
SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,
加载实现类。这样可以在运行时,动态为接口替换实现类。
正因此特性,我们可以很容易的通过 SPI 机制为我们的程序提供拓展功能。
1、 打开 idea 创建一个 Maven 工程 javaSPI 工程,
新建一个接口 Zsf.java 和两个实现类 BruceLeeImpl.java, JetLiImpl.java
/**
* C:\java-test\idea2019\javaSPI\src\main\java\djh\it\service\Zsf.java
*
* 2024-3-14 java 原生 SPI 代码实现:接口类 Zsf.java
*/
package djh.it.service;
public interface Zsf {
void service();
}
/**
* C:\java-test\idea2019\javaSPI\src\main\java\djh\it\service\impl\BruceLeeImpl.java
*
* 2024-3-14 java 原生 SPI 代码实现:实现类 BruceLeeImpl.java
*/
package djh.it.service.impl;
import djh.it.service.Zsf;
public class BruceLeeImpl implements Zsf {
@Override
public void service() {
System.out.println("李小龙(1940年11月27日-1973年7月20日),\n" +
"本名李振藩,族名李源鑫,出生于美国加利福尼亚州旧金山,\n" +
"祖籍中国广东省顺德市均安镇,毕业于华盛顿大学,\n" +
"华语武打男演员、武术技击家、武术哲学家、武术宗师,世界武道变革先驱者、\n" +
"功夫片的开创者、截拳道创始人、中国功夫第一位全球推广者。\n\n");
}
}
/**
* C:\java-test\idea2019\javaSPI\src\main\java\djh\it\service\impl\JetLiImpl.java
*
* 2024-3-14 java 原生 SPI 代码实现:实现类 JetLiImpl.java
*/
package djh.it.service.impl;
import djh.it.service.Zsf;
public class JetLiImpl implements Zsf {
@Override
public void service() {
System.out.println("李连杰(Jet Li),1963年4月26日生于中国北京市,\n" +
"祖籍辽宁省沈阳市,新加坡籍男演员、导演、制片人、武打演员。\n" +
"武术套路全能冠军,功夫动作潇洒飘逸,被美誉为功夫皇帝。\n");
}
}
2、创建新目录:resources/META-INF/services/
在新目录下,创建接口 Zsf 类的全类名 配置文件 djh.it.service.Zsf
## C:\java-test\idea2019\javaSPI\src\main\resources\META-INF\services\djh.it.service.Zsf
djh.it.service.impl.BruceLeeImpl
djh.it.service.impl.JetLiImpl
3、新建测试类 SpiTest.java
/**
* C:\java-test\idea2019\javaSPI\src\main\java\djh\it\test\SpiTest.java
*
* 2024-3-14 java 原生 SPI 代码实现:测试类 SpiTest.java
*/
package djh.it.test;
import djh.it.service.Zsf;
import java.util.Iterator;
import java.util.ServiceLoader;
public class SpiTest {
// psvm + Enter : 快速输出 main() 方法
public static void main(String[] args) {
ServiceLoader<Zsf> serviceLoader = ServiceLoader.load(Zsf.class);
Iterator<Zsf> iterable = serviceLoader.iterator();
while (iterable.hasNext()){
Zsf zsfImpl = iterable.next();
zsfImpl.service();
}
}
}
4、运行 main() 方法,就会读取配置文件,获得接口实现类,调用里面的方法,运行如下:
李小龙(1940年11月27日-1973年7月20日),
本名李振藩,族名李源鑫,出生于美国加利福尼亚州旧金山,
祖籍中国广东省顺德市均安镇,毕业于华盛顿大学,
华语武打男演员、武术技击家、武术哲学家、武术宗师,世界武道变革先驱者、
功夫片的开创者、截拳道创始人、中国功夫第一位全球推广者。
李连杰(Jet Li),1963年4月26日生于中国北京市,
祖籍辽宁省沈阳市,新加坡籍男演员、导演、制片人、武打演员。
武术套路全能冠军,功夫动作潇洒飘逸,被美誉为功夫皇帝。