什么是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. Java中邮件发送session.getDefaultInstance和getInstance的区别

    假设你想要同时用两个邮箱分别给再给两个邮箱发送邮件时,你就需要创建两个java.mail.Session对象,这时候你用getDefaultInstance的话会发现第二个Session对象和第一个对 ...

  2. freeswitch的任务引擎实现分析

    概述 freeswitch核心框架中有一个定时任务系统,在开发过程中用来做一些延时操作和异步操作很方便. 我们在VOIP的呼叫流程中,经常会有一些对实时性要求没那么高的操作,或者会有阻塞流程的操作,我 ...

  3. Linux性能优化实战CPU篇之总结(四)

    一.分析CPU瓶颈 1,性能指标 a>CPU使用率 CPU使用率描述了非空闲时间占总CPU时间的百分比,根据CPU上运行任务的不同可以分为:用户CPU.系统CPU.等待I/O CPU.软中断和硬 ...

  4. HDFS成员的工作机制

    NameNode工作机制 nn负责管理块的元数据信息,元数据信息为fsimage和edits预写日志,通过edits预写日志来更新fsimage中的元数据信息,每次namenode启动时,都会将磁盘中 ...

  5. 【计算机】CPU工作方式、多核心、超线程技术详解

    CPU架构要谈超线程和多核,就不得不谈CPU的架构和逻辑.无关的技术细节太多,这里略去.我们重点谈一下CPU中两个相关的模块:1)Processing Unit(运算处理单元),简称PU2)Archi ...

  6. 【C# 程序集】在.net中使用GAC 全局程序集缓存

    原文地址:https://blog.alswl.com/2011/01/gac/ GAC GAC是什么?是用来干嘛的?GAC的全称叫做全局程序集缓存,通俗的理解就是存放各种.net平台下面需要使用的d ...

  7. RadioButtton

    activity_radio_button.xml <?xml version="1.0" encoding="utf-8"?> <Relat ...

  8. linux配置vnc server,并用vnc viewer连接server

    做过Linux运维的朋友都知道,我们一般很少直接与服务器接触.都是通过终端来连接处理一些事物. 本人常用的终端有图形界面的是vnc viewer还有命令行界面xshell,当然各有千秋,喜欢使用哪个都 ...

  9. cmd:WIN7操作系统下cmd窗口下的复制粘贴

    1.右击cmd的顶部栏,点开属性 2.在 选项 下,勾选"快速编辑模式" 3.按住鼠标左键标注需要复制的区域 再点击一下右键,则上文的标记区域就已经被复制了,可以通过ctrl+v进 ...

  10. 文件上传漏洞靶机upload-labs(1到10)

    前言 项目地址:https://github.com/c0ny1/upload-labs pass-01(前端验证) 绕过方法:https://www.cnblogs.com/bk76120/p/12 ...