SPI

作者: ben大福 | 来源:发表于2019-06-19 11:15 被阅读0次

    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)
    

    相关文章

      网友评论

          本文标题:SPI

          本文链接:https://www.haomeiwen.com/subject/evuhqctx.html