Java基础系列-SPI你认识吗

作者 : 开心源码 本文共1564个字,预计阅读时间需要4分钟 发布时间: 2022-05-12 共187人阅读

原创文章,转载请标注出处:《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<>();

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Java基础系列-SPI你认识吗

发表回复