SPI简单解析
什么是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简单解析的更多相关文章
- 对 cloudwu 简单的 cstring 进行简单解析
题外话 以前也用C写过字符串,主要应用的领域是,大字符串,文件读取方面.写的很粗暴,用的凑合着.那时候看见云风前辈的一个开源的 cstring 串. 当时简单观摩了一下,觉得挺好的.也没细看.过了较长 ...
- 基于DOM的XSS注入漏洞简单解析
基于DOM的XSS注入漏洞简单解析http://automationqa.com/forum.php?mod=viewthread&tid=2956&fromuid=21
- 15.5 自学Zabbix之路15.5 Zabbix数据库表结构简单解析-其他 表
点击返回:自学Zabbix之路 自学Zabbix之路15.5 Zabbix数据库表结构简单解析-其他 表 1. Actions表 actions表记录了当触发器触发时,需要采用的动作. 2.Aler ...
- 深度优先搜索DFS和广度优先搜索BFS简单解析(新手向)
深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每个点仅被访问一次,这个过程就是图的遍历.图的遍历常用的有深度优先搜索和广度优先搜索,这两者对于有向图和无向图 ...
- List<T>集合的Sort自定义排序用法简单解析
List<T>集合的Sort自定义排序用法简单解析: 如下:一系列无序数字,如果想要他们倒序排列,则使用如下代码: 那么如何理解这段代码呢? (x,y)表示相邻的两个对象,如果满足条件:x ...
- Maven项目pom.xml文件简单解析
Maven项目pom.xml简单解析 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="h ...
- 自学Zabbix之路15.1 Zabbix数据库表结构简单解析-Hosts表、Hosts_groups表、Interface表
点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 自学Zabbix之路15.1 Zabbix数据库表结构简单解析-Hosts表.Hosts_grou ...
- 自学Zabbix之路15.2 Zabbix数据库表结构简单解析-Items表
点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 自学Zabbix之路15.2 Zabbix数据库表结构简单解析-Items表 Items表记录了i ...
- 自学Zabbix之路15.3 Zabbix数据库表结构简单解析-Triggers表、Applications表、 Mapplings表
点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 自学Zabbix之路15.3 Zabbix数据库表结构简单解析-Triggers表.Applica ...
随机推荐
- FSAF:嵌入anchor-free分支来指导acnhor-based算法训练 | CVPR2019
FSAF深入地分析FPN层在训练时的选择问题,以超简单的anchor-free分支形式嵌入原网络,几乎对速度没有影响,可更准确的选择最优的FPN层,带来不错的精度提升 来源:晓飞的算法工程笔记 公 ...
- NSSCTF-[SWPU 2019]Network
下载附件打开之后发现是和ascii比较像,但是尝试解码发现不是ascii,然后这里问了一下大佬然后又翻了一下自己的笔记,最后发现是TTL,这里直接上脚本, import binascii with o ...
- Visual Studio 的快捷不能用时候,我们只要选择重置就可以用了。
当发现Visual Studio 的快捷不能用时候,我们只要选择重置就可以用了.
- PyTorch深度学习实践-Overview
Overview 1.PyTorch简介 PyTorch是一个基于Torch的Python开源机器学习库,用于自然语言处理等应用程序.它主要由Facebookd的人工智能小组开发,不仅能够 实现强 ...
- anaconda及jupyter notebook的了解及使用方法(1)
今日内容 anaconda软件使用 jupyter notebook基本使用及快捷键 numpy anaconda软件使用 1.进入anaconda主页点击jupyter启动即可 呼起一个jupyte ...
- Tableau学习Step6一如何制作炫彩地图
Tableau学习Step6一如何制作炫彩地图 本文首发于博客冰山一树Sankey,去博客浏览效果更好. 一.统计地图概述 1.1 统计地图的基本概念 统计地图的本质:数据的正确对应 将数据信息和地理 ...
- C# HttpClient类库
示例代码: 1 using System.Net.Http; 2 using System.Net.Http.Headers; 3 using System.Threading.Tasks; 4 5 ...
- js location.href 和 php header 跳转方式
if ($result){ echo '添加成功';// header('refresh:3,url=user_nameList.php'); echo "<script> al ...
- Linux安装JDK8环境
1.下载JDK包 点击同意下载后,会让你注册oracel账号,登录了才能下载 2.上传到linux服务器,然后解压 解压命令(注意jdk的版本名称不一定相同): tar -zxvf jdk-8u181 ...
- elasticsearch高亮之词项向量
一.什么是词项向量 词项向量(term vector)是有elasticsearch在index document的时候产生,其包含对document解析过程中产生的分词的一些信息,例如分词在字段值中 ...