美文网首页程序员JAVA
Java基础系列-SPI你认识吗

Java基础系列-SPI你认识吗

作者: 唯一浩哥 | 来源:发表于2019-03-06 18:04 被阅读41次

原创文章,转载请标注出处:《Java基础系列-SPI你认识吗》


一、SPI是什么

SPI是相对API而言的。

API指的是应用对服务调用方提供的接口,用于提供某种服务、功能,面向的是服务调用方。

SPI指的是应用对服务实现方提供的接口,用于实现某种服务、功能,面向的是服务实现方

二、SPI的使用

2.1 第一步:创建服务接口

package com.dh.spi;

public interface Fruit {
    String getName();
}

2.2 第二步:创建多个服务实现

package com.dh.spi;

public class Apple implements Fruit {
    @Override
    public String getName() {
        return "apple";
    }
}
package com.dh.spi;

public class Banana implements Fruit {
    @Override
    public String getName() {
        return "Banana";
    }
}

这里的两个服务实现类,针对的是两个服务实现方,一方实现了Apple,另一方实现了Banana。

2.3 第三步:创建配置文件

在resource下创建/META-INF/services目录,在services目录下创建以服务接口全限定名为名称的文件:com.dh.spi.Fruit

文件内容为,当前服务实现的服务实现者类的全限定名

com.dh.spi.Apple

2.4 第四步:创建测试类

public class Test {
    public static void main(String[] args) {
        ServiceLoader<Fruit> s = ServiceLoader.load(Fruit.class);
        Iterator<Fruit> it = s.iterator();
        while(it.hasNext())
            System.out.println(it.next().getName());
    }
}

执行结果为:

apple

三、SPI的实现原理

SPI的实现主要依靠的就是ServiceLoader类。使用该类加载接口类型(例如:Fruit.class)

ServiceLoader<Fruit> s = ServiceLoader.load(Fruit.class);

虽然是一个load方法,但是并没有加载到指定的服务实现类,这里仅仅是对加载服务实现类做一些准备工作:

  • 创建ServiceLoader
  • 为service赋值
  • 为loader赋值
  • 为acc赋值
  • 清空providers缓存
  • 为lookupIterator赋值,其实就是创建一个LazyIterator延迟迭代器。

然后创建迭代器:

Iterator<Fruit> it = s.iterator();

iterator方法中采用了匿名内部类的方式定义了一个新的迭代器,这个迭代器中每一个方法都是通过调用之前创建好的延迟迭代器lookupIterator来完成的

最后就是进行迭代加载了。

while(it.hasNext())
    System.out.println(it.next().getName());

hasNext方法调用了延迟迭代器的hasNext方法,内部调用了hasNextService方法,在这个方法中就会设法去找到指定名称(META-INF/services/+接口全限定名)的资源文件。并完成读取文件内容的操作。

然后执行it.next()操作,这个又会调用延迟迭代器的对应方法hasNext,内部调用了nextService方法,这个方法主要功能就是加载上面从文件中读取到的全限定名称表示的类。并生成实例,将实例保存到providers中。

private LinkedHashMap<String,S> providers = new LinkedHashMap<>();

相关文章

  • Java基础系列-SPI你认识吗

    原创文章,转载请标注出处:《Java基础系列-SPI你认识吗》 一、SPI是什么 SPI是相对API而言的。 AP...

  • java基础:HashMap — 源码分析

    其他更多java基础文章:java基础学习(目录) 学习资料Java 8系列之重新认识HashMapJava集合:...

  • Awesome Java

    基础 Java 入门与实践 Java 语法清单 Java 8 系列之重新认识 HashMap Java 浮点数精确...

  • java基础-spi

    SPI SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现...

  • Java - SPI机制

    Java - SPI机制 SPI是什么 SPI全称Service Provider Interface,是Java...

  • dubbo 源码分析 -SPI

    dubbo 中大量使用SPI,在看源码之前必须先了解dubbo的SPI 1、Java原生spi java原生spi...

  • spi

    java中有一些包结尾为spi,如java.nio.channels.spi spi - service prov...

  • 4.Dubbo的SPI扩展点加载机制

    4.1 加载机制概述 4.1.1 Java SPI 在讲Dubbo SPI之前,先来了解一下Java SPI,SP...

  • Java基础:注解

    系列阅读 Java基础:类加载器 Java基础:反射 Java基础:注解 Java基础:动态代理 1. 概述 注解...

  • Dubbo SPI的认识

    Dubbo是基于Java原生SPI机制思想的一个改进. 关于JAVA 的SPI机制 SPI全称(service p...

网友评论

    本文标题:Java基础系列-SPI你认识吗

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