1 SPI机制简介

SPI的全名为Service Provider Interface.大多数开发人员可能不熟悉,因为这个是针对厂商或者插件的。在java.util.ServiceLoader的文档里有比较详细的介绍。简单的总结下java spi机制的思想。我们系统里抽象的各个模块,往往有很多不同的实现方案,比如日志模块的方案,xml解析模块、jdbc模块的方案等。面向的对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。 java spi就是提供这样的一个机制:为某个接口寻找服务实现的机制。有点类似IOC的思想,就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要。

2 SPI具体约定

java spi的具体约定为:当服务的提供者,提供了服务接口的一种实现之后,在jar包的META-INF/services/目录里同时创建一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类。而当外部程序装配这个模块的时候,就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入。 基于这样一个约定就能很好的找到服务接口的实现类,而不需要再代码里制定。jdk提供服务实现查找的一个工具类:java.util.ServiceLoader

3 应用场景


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文件里指定实现类的方式来暴露驱动提供者.

4 案例说明

一个内容管理系统有一个搜索模块。是基于接口编程的。搜索的实现可能是基于文件系统的搜索,也可能是基于数据库的搜索

接口定义如下

  1. package my.xyz.spi;
  2. import java.util.List;
  3. public interface Search {
  4. public List serch(String keyword);
  5. }

A公司采用文件系统搜索的方式实现了 Search接口,B公司采用了数据库系统的方式实现了Search接口

A公司实现的类  com.A.spi.impl.FileSearch

B公司实现的类  com.B.spi.impl.DatabaseSearch

那么A公司发布 实现jar包时,则要在jar包中META-INF/services/my.xyz.spi.Search文件中写下如下内容

com.A.spi.impl.FileSearch

那么B公司发布 实现jar包时,则要在jar包中META-INF/services/my.xyz.spi.Search文件中写下如下内容

com.B.spi.impl.DatabaseSearch

  1. package com.xyz.factory;
  2. import java.util.Iterator;
  3. import java.util.ServiceLoader;
  4. import my.xyz.spi.Search;
  5. public class SearchFactory {
  6. private SearchFactory() {
  7. }
  8. public static Search newSearch() {
  9. Search search = null;
  10. ServiceLoader<Search> serviceLoader = ServiceLoader.load(Search.class);
  11. Iterator<Search> searchs = serviceLoader.iterator();
  12. if (searchs.hasNext()) {
  13. search = searchs.next();
  14. }
  15. return search;
  16. }
  17. }
  1. package my.xyz.test;
  2. import java.util.Iterator;
  3. import java.util.ServiceLoader;
  4. import com.xyz.factory.SearchFactory;
  5. import my.xyz.spi.Search;
  6. public class SearchTest {
  7. public static void main(String[] args) {
  8. Search search = SearchFactory.newSearch();
  9. search.serch("java spi test");
  10. }
  11. }

java中的SPI机制的更多相关文章

  1. 【Java】深入理解Java中的spi机制

    深入理解Java中的spi机制 SPI全名为Service Provider Interface是JDK内置的一种服务提供发现机制,是Java提供的一套用来被第三方实现或者扩展的API,它可以用来启用 ...

  2. 结合实战和源码来聊聊Java中的SPI机制?

    写在前面 SPI机制能够非常方便的为某个接口动态指定其实现类,在某种程度上,这也是某些框架具有高度可扩展性的基础.今天,我们就从源码级别深入探讨下Java中的SPI机制. 注:文章已收录到:https ...

  3. Java 中的 SPI 机制是什么鬼?高级 Java 必须掌握!

    作者:sigangjun blog.csdn.net/sigangjun/article/details/79071850 SPI的全名为:Service Provider Interface,大多数 ...

  4. java中的spi

    JAVA中的SPI机制 1.SPI简介 SPI机制(Service Provider Interface)其实源自服务提供者框架(Service Provider Framework),是一种将服务接 ...

  5. 一文搞懂Java/Spring/Dubbo框架中的SPI机制

    几天前和一位前辈聊起了Spring技术,大佬突然说了SPI,作为一个熟练使用Spring的民工,心中一紧,咱也不敢说不懂,而是在聊完之后赶紧打开了浏览器,开始的学习之路,所以也就有了这篇文章.废话不多 ...

  6. Java中的SPI原理浅谈

    在面向对象的程序设计中,模块之间交互采用接口编程,通常情况下调用方不需要知道被调用方的内部实现细节,因为一旦涉及到了具体实现,如果需要换一种实现就需要修改代码,这违反了程序设计的"开闭原则& ...

  7. java中的反射机制在Android开发中的用处

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反 ...

  8. java中wait/notify机制

    通常,多线程之间需要协调工作.例如,浏览器的一个显示图片的线程displayThread想要执行显示图片的任务,必须等待下载线程 downloadThread将该图片下载完毕.如果图片还没有下载完,d ...

  9. 浅说Java中的反射机制(二)

    写过一篇Java中的反射机制,不算是写,应该是抄了,因为那是别人写的,这一篇也是别人写的,摘抄如下: 引自于Java基础--反射机制的知识点梳理,作者醉眼识朦胧.(()为我手记) 什么是反射? 正常编 ...

随机推荐

  1. Fiddler--一、HTTP协议简介

    在学习Fiddler之前,最好先学习一下HTTP协议. HTTP协议简介 什么是HTTP协议 超文本传输协议(HTTP)是一种通信协议,它允许将超文本标记语言(HTML)文档从Web服务器传送到客户端 ...

  2. 环境搭建系列-系统安装之centos 6.5安装与配置

    按照国际惯例,系列目录先奉上: 系列一:系统安装之centos 6.5安装与配置 系列二:准备工作之Java环境安装 系列三:数据为先之MySQL读写集群搭建 系列四:谈分布式之RabbitMQ集群搭 ...

  3. EXISTS 引入子查询时,在选择列表中只能指定一个表达式

  4. 前端学PHP之PDO基础操作

    × 目录 [1]创建PDO [2]使用PDO [3]事务处理 前面的话 PDO(php data object)扩展类库为php访问数据库定义了轻量级的.一致性的接口,它提供了一个数据库访问抽象层,这 ...

  5. C#/VB.NET Excel数据分列

    C#/VB.NET Excel数据分列 有时候我们需要将保存在Excel单元格中的组合型数据拆分为多列(如将全名拆分为姓和名两列)以方便我们处理.记忆或保存.为了避免重复和大量的手动输入工作,Exce ...

  6. Oracle 11g DG配置简明版

    环境: 主库A机:在线生产环境,RHEL 6.4 + Oracle 11.2.0.3 备库B机:新增备机,RHEL 6.4 需求: 对生产环境最小影响前提下配置DG备库. 目录: 一.B机安装相同版本 ...

  7. Anliven - To-Do List

    2016 - December Name Type Start Deadline Status Output Comments Last Review SQL必知必会(第4版) Book 2016-1 ...

  8. Android重构与设计之路,从整理提示弹窗(SmartAlertPop)开始

    封装一个独立弹窗Module,这里的弹窗包括普通的Dialog方式弹框和WindowManager方式弹窗.提供一种管理项目里面弹窗的方案,便于后期修改和维护. 首先描述一个在大项目中普遍存在的一个现 ...

  9. 微信小程序(微信应用号)开发ide安装解决方法

    这两天整个技术圈都炸锅了,微信小程序(微信应用号)发布内测,首批200家收到邀请,但是没受邀请的同学,也不用担心,下面介绍一下解决方法. 首先需要下载ide,昨天只需要下载0.9版本的编辑器并替换文件 ...

  10. Python中的类、对象、继承

    类 Python中,类的命名使用帕斯卡命名方式,即首字母大写. Python中定义类的方式如下: class 类名([父类名[,父类名[,...]]]): pass 省略父类名表示该类直接继承自obj ...