之前开阿里的HSF框架,里面用到了Java的SPI机制,今天闲暇的时候去了解了一下,通过写博客来记录一下

SPI的全名为Service Provider Interface,我对于该机制的理解是为接口寻找服务实现类。现在公司的系统都是进行了模块的划分,系统抽象为多个模块,往往有很多不同的实现方案,比如日志模块的方案,xml解析模块、jdbc模块的方案等。面向的对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。于是就有了SPI这种服务发现机制。

java spi的具体使用如下  :

当服务的提供者,提供了服务接口的一种实现之后,在jar包的META-INF/services/目录里同时创建一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类。而当外部程序装配这个模块的时候,就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入。

基于这样一个约定就能很好的找到服务接口的实现类,而不需要再代码里制定。

jdk提供服务实现查找的一个工具类:java.util.ServiceLoader

参考案例:

项目文件结构:

参考代码:

Developer.javapackage cn.edu.knowledge.spi;public interface Developer {public String getPrograme();}

JavaDeveloper.javapackage cn.edu.knowledge.spi;public class JavaDeveloper implements Developer {@Overridepublic String getPrograme() {return "Java";}
}

META-INF\services文件下的cn.edu.knowledge.spi.Developer文件内容是服务类的全限命名:

cn.edu.knowledge.spi.JavaDeveloper

将文件导出为jar包,新建一个项目,在项目中导入该jar,下面的测试类的代码

Test.javaimport java.util.ServiceLoader;
import cn.edu.knowledge.spi.Developer;
public class Test {public ServiceLoader<Developer> serviceloader = ServiceLoader.load(Developer.class);public static void main(String[] arg) {Test devClient = new Test();Developer dev = devClient.getDeveloper();System.out.println(dev.getPrograme());}private Developer getDeveloper() {Developer lastdev = null;for (Developer dev : serviceloader) {System.out.println("out." + dev.getPrograme());lastdev = dev;}if(lastdev==null)System.out.println("why...");return lastdev;}}

我们在开发中都有用到SPI机制,但是我们没有意识到比如:

1.common-logging

apache最早提供的日志的门面接口。只有接口,没有实现。具体方案由各提供商实现,发现日志提供商是通过扫描  META-INF/services/org.apache.commons.logging.LogFactory 配置文件,通过读取该文件的内容找到日志提工商实现类。只要我们的日志实现里包含了这个文件,并在文件里制定   LogFactory工厂接口的实现类即可。

2.jdbc

jdbc4.0以前,开发人员还需要基于Class.forName("xxx")的方式来装载驱动,jdbc4也基于spi的机制来发现驱动提供商了,可以通过META-INF/services/java.sql.Driver文件里指定实现类的方式来暴露驱动提供者。

学习到的知识:面向接口编程可以实现接口和实现的分离,这样做的最大好处就是能够在客户端未知的情况下修改实现代码。那么什么时候应该抽象出Java接口呢?一种是用在层和层之问的调用。层和层之间是最忌讳耦合度过高或是改变过于频繁。设计优秀的接口能够解决这个问题。另一种是用在那些不稳定的部分上。如果某些需求的变化性很大,那么定义接口也是一种解决之道。设计良好的接口就像是我们日常使用的万用插座一样,不论插头如何变化,都可以使用。

Java之SPI机制相关推荐

  1. 高级开发必须理解的Java中SPI机制

    本文通过探析JDK提供的,在开源项目中比较常用的Java SPI机制,希望给大家在实际开发实践.学习开源项目提供参考. 1 SPI是什么 SPI全称Service Provider Interface ...

  2. 深入了解Java的SPI机制

    导语   SPI的全名叫做Service Provider Interface,在java.util.ServiceLoader的文档中有详细的介绍,下面就来通过简单的例子实现SPI深入了解   我们 ...

  3. 【java】SPI机制详解

    1.概述 以前的文章:[SPI]java基础之SPI框架实现 转载:Java常用机制 - SPI机制详解 PI(Service Provider Interface),是JDK内置的一种 服务提供发现 ...

  4. Java的SPI机制

    Dubbo等框架使用到必须掌握. java.sql.Driver 是 Spi,com.mysql.jdbc.Driver 是 Spi 实现,其它的都是 Api. package org.hadoop. ...

  5. JDK源码分析——Java的SPI机制分析与实战

    重点提示:在我博客中的所有的源码分析的实例,我都将会放到github上,感兴趣的朋友可以下载下来调试运行,我相信还是可以有所收获的.我的目的是让所有读到我博客的朋友都可以了解到有价值的东西,学习到ja ...

  6. java实践SPI机制及浅析源码

    1.概念 正式步入今天的核心内容之前,溪源先给大家介绍一下关于SPI机制的相关概念,最后会提供实践源代码. SPI即Service Provider Interface,属于JDK内置的一种动态的服务 ...

  7. JAVA的SPI机制究竟是什么玩意儿?为什么要有?怎么使用呢?

    SPI是什么玩意儿: SPI:全名为Service Provider Interface,我对于该机制的理解是为接口寻找服务实现类.现在公司的系统都是进行了模块的划分,系统抽象为多个模块,往往有很多不 ...

  8. java中spi机制解读

    关于spi机制大部分人都很陌生,因为我们在开发过程中很少用到,但是实际上这个机制从我们接触java开始就跟我们如影随形.有些人认为使用java很简单,都是调用第三方依赖包,然后结合自己的业务逻辑就可以 ...

  9. 我崩溃了!月薪30K必须掌握的开源项目Java中SPI机制

    前言 Spring 是一个非常流行和成功的 Java 应用开发框架.Spring Security 是 Spring 家族中的一个安全管理框架,提供了一套 Web 应用安全性的完整解决方案.在用户认证 ...

最新文章

  1. Oracle安装部署之rhel 5.8下静默安装oracle11gr2
  2. pyinstaller 'utf-8' codec can't decode byte 0xce in position 123: invalid continuation byte
  3. python not instance_python isinstance 判断各种类型的小细节|python3教程|python入门|python教程...
  4. 关于DataFormWebPart中CreatedModifiedInfo信息的分开使用
  5. 力扣——k个一组翻转链表
  6. LeetCode 278. First Bad Version
  7. Ble扫描导致wifi信号弱/断开解决
  8. 解决无线网连不上的问题
  9. python基础(12):Standard Library标准库(包含正则)
  10. SAP各模块常用数据库表大全--->常用表
  11. 简单的C语言顺序结构例题介绍
  12. Vuepress 如何引入百度统计和谷歌统计
  13. web.py mysql_webpy连接mysql出现问题
  14. 六 R语言barplot条形图之带误差棒的对称条形图及相关性分析结果分布
  15. 修改MAC密码 Navicat每次打开都要输入密码
  16. 魔数湖南大学程序设计作业
  17. js 监听esc按键
  18. 数字图像处理 图像形态学处理
  19. python从入门到实践答案博客园_Python编程:从入门到实践——【作业】——第四章(操作列表)...
  20. 医院信息化成功的关键=本质+方法+工具

热门文章

  1. PDF转Word的免费方法
  2. linux socket 多人聊天软件,Linux Socket编程---TCP实现多客户端的网络聊天室
  3. java斐波那切数列_Java中的递归方法
  4. WebLogic重启
  5. 初识Python之安装—anaconda pycharm区别
  6. 数据流图中flow不显示文字_利用Flow来进行旋转流体仿真
  7. jquery ajax 找到数据怎样放到下拉框里_闲话Excel之简易数据动态图表的制作
  8. OpenCV—图像椒盐噪声生成器
  9. 我的Linux系统入坑之路!!!!
  10. 数百个 HTML5 例子学习 HT 图形组件 – 拓扑图篇