Java基础系列-SPI你认识吗
原创文章,转载请标注出处:https://www.cnblogs.com/V1haoge/p/10755313.html
一、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你认识吗的更多相关文章
- 2015年12月28日 Java基础系列(六)流
		
2015年12月28日 Java基础系列(六)流2015年12月28日 Java基础系列(六)流2015年12月28日 Java基础系列(六)流
 - Java基础系列--static关键字
		
原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/8477914.html 一.概述 static关键字是Java诸多关键字中较常使用的一个,从 ...
 - Java基础系列-ArrayList
		
原创文章,转载请标注出处:<Java基础系列-ArrayList> 一.概述 ArrayList底层使用的是数组.是List的可变数组实现,这里的可变是针对List而言,而不是底层数组. ...
 - Java基础系列-Collector和Collectors
		
原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/10748925.html 一.概述 Collector是专门用来作为Stream的coll ...
 - Java基础系列-二进制操作
		
原创文章,转载请标注出处:<Java基础系列-二进制操作> 概述 Java源码中涉及到大量的二进制操作,非常的复杂,但非常的快速. Java二进制表示法 首先了解下二进制,二进制是相对十进 ...
 - Java基础系列-equals方法和hashCode方法
		
原创文章,转载请标注出处:<Java基础系列-equals方法和hashCode方法> 概述 equals方法和hashCode方法都是有Object类定义的. publi ...
 - Java基础系列-Comparable和Comparator
		
原创文章,转载请标注出处:<Java基础系列-Comparable和Comparator> 一.概述 Java中的排序是由Comparable和Comparator这两个接 ...
 - Java基础系列--HashMap(JDK1.8)
		
原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/10022092.html Java基础系列-HashMap 1.8 概述 HashMap是 ...
 - 夯实Java基础系列1:Java面向对象三大特性(基础篇)
		
本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 [https://github.com/h2pl/Java-Tutorial](https: ...
 
随机推荐
- Codeforces 1337C  Linova and Kingdom
			
题意 给你一颗有根树,你要选择\(k\)个点,最大化\(\sum_{i \in S} val_i\),其中\(S\)是被选点的集合,\(val_i\)等于节点\(i\)到根的路径上未被选择点的个数. ...
 - Tomcat cluster方案共享session配置成功,yeah....
			
后继版本:https://www.cnblogs.com/xiandedanteng/p/12143112.html 参考网文: 1.Tomcat官方文档 2.https://blog.51cto.c ...
 - leetcode刷题-51N皇后
			
题目 n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击. 给定一个整数 n,返回所有不同的 n 皇后问题的解决方案. 每一种解法包含一个明确的 n 皇后问 ...
 - vueJs 安装
			
1.下载nodeJs 可前往 https://www.cnblogs.com/takeyblogs/p/13600124.html 这里下载 2.由于 npm 安装速度慢,本教程使用了淘宝的镜像及其命 ...
 - 接口自动化---简单的数据驱动框架ATP(基于excel)
			
数据驱动测试:根据数据进行测试.将用例写入excel文件,用代码读取文件中的数据,从而实现自动化测试. 自动化框架实现步骤: 1.获取用例 2.调用接口 3.校验结果 4.发送测试报告 5.异常处理 ...
 - DevOps-实践心得
			
基于最近几年从事与DevOps的相关实践,对这篇文章的观点深有体会,所以记录在这里.加粗部分是我比较深有体会的,但是对于最后作者对于"运维"有些悲观,我有点不敢苟同,反而对于运维的 ...
 - [04] C# Alloc Free编程之实践
			
C# Alloc Free编程之实践 上一篇说了Alloc Free编程的基本理论. 这篇文章就说怎么具体做实践. 常识 之所以说是常识, 那是因为我们在学任何一门语言的时候, 都能在各种书上看到各种 ...
 - 使用PXE+VNC方式安装CentOS 7
			
U盘坏了,用个下面的方法安装 安装配置dhcp yum -y install dhcp tftp-server 修改如下,网段改为你自己的网段 vim /etc/dhcp/dhcpd.conf sub ...
 - [LeetCode]23. 合并K个排序链表(优先队列;分治待做)
			
题目 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] 输出: 1 ...
 - C语言01
			
从问题到C语言程序设计 1.1计算机的问题求解方法 程序设计面向的问题 什么问题可以用程序的方法解决? 打印九九乘法表 图形变换 文件压缩问题 ....... 一切可计算的问题 如何解决? 确定问题可 ...