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
内部目录结构为

image.png
把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)
上一篇下一篇

猜你喜欢

热点阅读