1. 了解SPI机制
我们在平时学习和工作中总是会听到Java SPI机制,特别是使用第三方框架的时候,那么什么是SP机制呢?SPI 全称 Service Provider Interface,是 Java 提供的一套用来被第三方实现或者扩展的接口,它可以用来启用框架扩展和替换组件。 SPI 的作用就是为这些被扩展的 API 寻找服务实现。
2. 使用SPI机制
- 新建一个maven工程spiTest,包含两个子工程spiProvider、spiConsumer,工程结构如下:
-
在spiProvider工程中定义一个PowerJackInterface接口:
package com.jing.standard; /** * 电源插座接口 */ public interface PowerJackInterface { /** * 电源插座 */ void doPowerJack(); }
-
在spiProvider工程中提供一个实现类:
package com.jing.standard.impl; import com.jing.standard.PowerJackInterface; public class PowerJack110V implements PowerJackInterface { @Override public void doPowerJack() { System.out.println("这是110V电源插座!"); } }
-
在spiProvider工程中resource目录下创建
META-INF/services/
目录,并且创建一个名为com.jing.standard.PowerJackInterface
的文件,内容如下:com.jing.standard.impl.PowerJack110V
-
在spiConsumer工程中引入spiProvider工程:
<dependency> <groupId>com.jing</groupId> <artifactId>spiProvider</artifactId> <version>1.0.0-SNAPSHOT</version> </dependency>
-
在spiConsumer工程中进行方法调用:
package com.jing; import com.jing.standard.PowerJackInterface; import java.util.ServiceLoader; public class Main { public static void main(String[] args) { ServiceLoader loader = ServiceLoader.load(PowerJackInterface.class); loader.forEach(item -> { PowerJackInterface powerJackInterface = (PowerJackInterface) item; powerJackInterface.doPowerJack(); }); } }
-
运行结果:
这是110V电源插座!
-
在spiConsumer工程中也增加一个PowerJackInterface接口实现类:
package com.jing.service; import com.jing.standard.PowerJackInterface; public class PowerJack220V implements PowerJackInterface { @Override public void doPowerJack() { System.out.println("220V电源插座!"); } }
-
在spiConsumer工程中resource目录下创建
META-INF/services/
目录,并且创建一个名为com.jing.standard.PowerJackInterface
的文件,内容如下:com.jing.service.PowerJack220V
-
运行结果
220V电源插座! 这是110V电源插座!
3. SPI机制总结
JDK中的SPI实现,是由ServiceLoader类根据自定义传入类加载器或者应用程序类加载器在约定好的固定路径下(ClassPath:META-INF/services/)去查找和加载第三方接口实现类。
要使用JDK中的SPI机制有几个前提条件:
- 服务提供方必须实现目标接口
- 服务提供方必须在自身ClassPath:META-INF/services/路径下建立文件,文件名为目标接口全限定名;文件内容为实现目标接口的具体实现类全限定名。