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. redis的面试题

    1:使用redis有哪些好处? (1) 速度快,因为数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1) (2) 支持丰富数据类型,支持string,lis ...

  2. GitHub实战系列~2.把本地项目提交到github中 2015-12-10

    GitHub实战系列汇总:http://www.cnblogs.com/dunitian/p/5038719.html ———————————————————————————————————————— ...

  3. 【原】SDWebImage源码阅读(二)

    [原]SDWebImage源码阅读(二) 本文转载请注明出处 —— polobymulberry-博客园 1. 解决上一篇遗留的坑 上一篇中对sd_setImageWithURL函数简单分析了一下,还 ...

  4. 1、Python基础知识

    输出print “houkai”,3.0版本后print修改为函数,print(‘houkai’) 数学运算:默认整数整除1/2=0而1.0/2=0.5,可以使用from __future__ imp ...

  5. ASP.NET MVC5+EF6+EasyUI 后台管理系统(41)-组织架构

    系列目录 本节开始我们要实现工作流,此工作流可以和之前的所有章节脱离关系,也可以紧密合并. 我们当初设计的项目解决方案就是可伸缩可以拆离,可共享的项目解决方案.所以我们同时要添加App.Flow文件夹 ...

  6. jQuery:实现网页的打印功能

    实现的打印功能大致跟浏览器的 Ctrl+P 效果一样 一.直接上代码 <!DOCTYPE html> <head> <meta charset="utf-8&q ...

  7. Vertica 分区表设计

    Vertica数据库中的表只是一个逻辑概念. 实际存储在磁盘上的是projection. 当创建一张表,没有创建projection时,那么插入数据的时候会自动创建一个默认的projection.如果 ...

  8. SSE指令集学习:Compiler Intrinsic

    大多数的函数是在库中,Intrinsic Function却内嵌在编译器中(built in to the compiler). 1. Intrinsic Function Intrinsic Fun ...

  9. WinForm构造函数的作用

    最近练习C#项目:何问起收藏夹(HoverTreeSCJ),实现编辑网址时,遇到这个问题:比如打开窗口后,要自动显示数据.解决方法:那么可以通过窗体的构造函数传递参数. 比如窗体类: public p ...

  10. 《连载 | 物联网框架ServerSuperIO教程》- 8.单例通讯模式开发及注意事项

    1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...