什么是SPI 

一种服务加载方式,全名为Service Provider Interface,Service提供者接口

如果我们要抽象里面的模块,在面对对象编程当中,我们模块之间,一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。
一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。
为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。
有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要。所以SPI的核心思想就是解耦

通俗例子解释:

例子:
JDK中有支持音乐播放,假设只支持mp3的播放,有些厂商想在这个基础之上支持mp4播放,有的想支持mp5播放,
而这些厂商都是第三方厂商,如果没有提供SPI这种实现标准,那就只有修改JAVA的源代码了。
有了SPI标准,JDK的爸爸SUN公司只需要提供一个播放接口,在实现播放的功能上通过ServiceLoad的方式加载服务,
那么第三方只需要实现这个播放接口,再按SPI标准的约定进行打包,再放到classpath下面就OK了

SPI的机制约定:

1)         在jar包的META-INF/services/目录中创建以接口全限定名命名的文件该文件内容为Api具体实现类的全限定名

2)         服务调用方用java.util.ServiceLoader,用服务接口为参数,去动态加载具体的实现类到JVM中

3)         如SPI的实现类为Jar则需要放在主程序classPath中

4)         定义服务的通用接口,针对通用的服务接口,提供具体的实现类

//通用接口,
public interface SendMessage {
void send(String msg);
}
package com.quan.spi.emailimp;

import com.quan.spi.api.SendMessage;

//通用接口的实现类1
public class SendMessageEmail implements SendMessage { @Override
public void send(String msg) {
System.out.println("send " + msg +" use email"); }
}
package com.quan.spi.phoneimp;

import com.quan.spi.api.SendMessage;

//通用接口的实现类2
public class SendMessagePhone implements SendMessage {
@Override
public void send(String msg) {
System.out.println("send " +msg +" use phone");
}
}
//通过工厂模式去获得sendmessage
public class SendMessageFactory {
public SendMessageFactory() {
} public static SendMessage getsend(){
SendMessage sendMessage = null;
ServiceLoader<SendMessage> sendMessages = ServiceLoader.load(SendMessage.class);
Iterator iterator = sendMessages.iterator();
while (iterator.hasNext()){
sendMessage = (SendMessage) iterator.next();
sendMessage.send("quan");
}
return sendMessage;
}
}

META-INF/services:

名字为:com.quan.spi.api.SendMessage

com.quan.spi.emailimp.SendMessageEmail
com.quan.spi.phoneimp.SendMessagePhone

测试:

package com.quan.spi;

import com.quan.spi.api.SendMessage;
import org.junit.Test; import java.util.ServiceLoader; public class TestMessage {
@Test
public void Test(){
SendMessageFactory.getsend();
} @Test
public void Test2(){
ServiceLoader<SendMessage> sendMessages = ServiceLoader.load(SendMessage.class);
for (SendMessage s : sendMessages) {
s.send("quanquan");
}
} }

SPI简单解析的更多相关文章

  1. 对 cloudwu 简单的 cstring 进行简单解析

    题外话 以前也用C写过字符串,主要应用的领域是,大字符串,文件读取方面.写的很粗暴,用的凑合着.那时候看见云风前辈的一个开源的 cstring 串. 当时简单观摩了一下,觉得挺好的.也没细看.过了较长 ...

  2. 基于DOM的XSS注入漏洞简单解析

    基于DOM的XSS注入漏洞简单解析http://automationqa.com/forum.php?mod=viewthread&tid=2956&fromuid=21

  3. 15.5 自学Zabbix之路15.5 Zabbix数据库表结构简单解析-其他 表

    点击返回:自学Zabbix之路 自学Zabbix之路15.5 Zabbix数据库表结构简单解析-其他 表  1. Actions表 actions表记录了当触发器触发时,需要采用的动作. 2.Aler ...

  4. 深度优先搜索DFS和广度优先搜索BFS简单解析(新手向)

    深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每个点仅被访问一次,这个过程就是图的遍历.图的遍历常用的有深度优先搜索和广度优先搜索,这两者对于有向图和无向图 ...

  5. List<T>集合的Sort自定义排序用法简单解析

    List<T>集合的Sort自定义排序用法简单解析: 如下:一系列无序数字,如果想要他们倒序排列,则使用如下代码: 那么如何理解这段代码呢? (x,y)表示相邻的两个对象,如果满足条件:x ...

  6. Maven项目pom.xml文件简单解析

    Maven项目pom.xml简单解析 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="h ...

  7. 自学Zabbix之路15.1 Zabbix数据库表结构简单解析-Hosts表、Hosts_groups表、Interface表

    点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 自学Zabbix之路15.1 Zabbix数据库表结构简单解析-Hosts表.Hosts_grou ...

  8. 自学Zabbix之路15.2 Zabbix数据库表结构简单解析-Items表

    点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 自学Zabbix之路15.2 Zabbix数据库表结构简单解析-Items表 Items表记录了i ...

  9. 自学Zabbix之路15.3 Zabbix数据库表结构简单解析-Triggers表、Applications表、 Mapplings表

    点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 自学Zabbix之路15.3 Zabbix数据库表结构简单解析-Triggers表.Applica ...

随机推荐

  1. windows清理用户痕迹

    1.日志管理器的基本使用 在这里创建自定义视图是非常重要的 在设置自定义视图不必设置的事件日志选项太多,可以按日志也可以按源进行设置,根据自己的情况来做决定 在cmd下可以使用wevtutil cl ...

  2. ASP.NET Core 6框架揭秘实例演示[13]:日志的基本编程模式[上篇]

    <诊断跟踪的几种基本编程方式>介绍了四种常用的诊断日志框架.其实除了微软提供的这些日志框架,还有很多第三方日志框架可供我们选择,比如Log4Net.NLog和Serilog 等.虽然这些框 ...

  3. 【C# .Net GC】GC的类型与工作方式 和配置

    .net主要有两种类型垃圾回收器,也可也说是垃圾回收器的两种工作模式. GC的类型主要有两种: 工作模式是针对进程的,程序启动后就不能修改了.只能在配置文件.json .xml进行设置.但是可用通过G ...

  4. 【基础概念】匹夫细说C#:不是“栈类型”的值类型,从生命周期聊存储位置

    转载地址 https://www.cnblogs.com/murongxiaopifu/p/4419040.html 0x00 前言: 匹夫在日常和别人交流的时候,常常会发现一旦讨论涉及到" ...

  5. Python:numpy.ma模块

    翻译总结自:The numpy.ma module - NumPy v1.21 Manual 前言 ma是Mask的缩写,关于Mask的解释,如果有PS的基础,可以理解为蒙版,如果有计算机网络的基础, ...

  6. Qt:QCustomPlot使用教程(三)——用户交互

    0.说明 本节翻译总结自:Qt Plotting Widget QCustomPlot - User Interactions 本节内容是使用QCustomPlot实现绘图和用户交互功能. 本文代码中 ...

  7. 网络爬虫深究-初识HTTP和https常识

    网络爬虫专题--HTTP基本原理 URI和URL.URN的关系 超文本 HTTP和HTTPS URI和URL 首先,我们来了解一下URI和URL,URI,即统一资源标志符,URL,即统一资源定位符. ...

  8. JZ-065-矩阵中的路径

    矩阵中的路径 题目描述 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子.如果一条路 ...

  9. linux作业--第三周

    1.统计出/etc/passwd文件中其默认shell为非/sbin/nologin的用户个数,并将用户都显示出来 [root@localhost ~]# cat /etc/passwd | grep ...

  10. php 23种设计模型 - 组合模式(合成模式)

    组合模式(Composite) 组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次.这 ...