SPI
2019-06-19 本文已影响0人
ben大福
SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制。
一个服务(Service)通常指的是已知的接口或者抽象类,服务提供方就是对这个接口或者抽象类的实现,然后按照SPI 标准存放到资源路径META-INF/services目录下,文件的命名为该服务接口的全限定名。
通俗来讲就是我们只是保留了一个接口的调用,程序运行时需要将该接口具体实现的类通过ClassLoader加载到JVM中,然后接口的调用就可以转变成具体的实现调用。从而到达在程序运行时动态给接口寻找接口的具体实现
service目录下的规范可以参考:https://blog.csdn.net/u012410733/article/details/52475039
外部实现结构为
image.png
使用jdk自带的jar命令打包 生成view.jar
jar cvf view.jar
内部目录结构为
把view.jar 加入到classpath中并运行Main.class
java -classpath $CLASS_PATH:View.jar zmw.spi.Main
各类的代码
package zmw.spi;
public class Main {
public static void main(String args[]) {
AtomicInteger atomicInteger = new AtomicInteger(1);
ServiceLoader<View> serviceLoader = ServiceLoader.load(View.class);
Iterator<View> it = serviceLoader.iterator();
System.out.println("get service loader");
while (it.hasNext()) {
System.out.println("get service" + atomicInteger.getAndIncrement());
it.next().render();
}
System.out.println("get service loader end");
}
}
package zmw.spi;
public interface View {
void render();
}
package zmw.spi;
public class TextView implements View {
public TextView() {
}
public void render() {
System.out.println("text view");
}
}
package zmw.spi;
public class HtmlView implements View {
@Override
public void render() {
System.out.println("html view");
}
}
ServiceLoader 动态加载meta-inf中的类
ServiceLoader.load(service) -> ServiceLoader.load(service, cl) -> new ServiceLoader<>(service, loader) -> new LazyIterator(service, loader)