java Service Provider Interface 简单示例

转载 2017年07月17日 18:10:45

SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制。 目前有不少框架用它来做服务的扩展发现, 简单来说,它就是一种动态替换发现的机制, 举个例子来说, 有个接口,想运行时动态的给它添加实现,你只需要添加一个实现,

而后,把新加的实现,描述给JDK知道就行啦(通过改一个文本文件即可) 公司内部,目前Dubbo框架就基于SPI机制提供扩展功能。

简单示例

通过一个简单例子来说明SPI是如何使用的。 首先通过一张图来看看,用SPI需要遵循哪些规范,因为spi毕竟是JDK的一种标准。  我们首先需要一个目录,META-INF\services 如下,最终的目录路径就像这样:

1
2
3
4
5
6
7
8
9
10
11
12
└── src
├── com
│   └── ivanzhang
│       └── spi
│           ├── HelloInterface.java
│           ├── impl
│           │   ├── ImageHello.java
│           │   └── TextHello.java
│           └── SPIMain.java
└── META-INF
    └── services
        └── com.ivanzhang.spi.HelloInterface

文件名字为 接口/抽象类: 全名 文件内容: 接口/抽象类 实现类

就像这样: com.ivanzhang.spi.impl.TextHello com.ivanzhang.spi.impl.ImageHello

接下来, 我们需要定义接口和实现类:

1
2
3
public interface HelloInterface {
  public void sayHello();
}

实现类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class TextHello implements HelloInterface {

  @Override
  public void sayHello() {
      System.out.println("Text Hello.");
  }

}

public class ImageHello implements HelloInterface {
  @Override
  public void sayHello() {
      System.out.println("Image Hello");
  }
}

最后,来看看,如果使用SPI机制,客户端代码:

1
2
3
4
5
6
7
8
9
10
11
public class SPIMain {
    public static void main(String[] args) {

        ServiceLoader<HelloInterface> loaders = 
              ServiceLoader.load(HelloInterface.class);

        for (HelloInterface in : loaders) {
            in.sayHello();
        }
    }
}

最后的输出: Text Hello.Image Hello

一个服务(service)通常指的是已知的接口或者抽象类,服务提供方就是对这个接口或者抽象类的实现,然后按spi标准存放到资源路径META-INF/services目录下,文件的命名为该服务接口的全限定名。如有一个服务接口com.test.Service,其服务实现类为com.test.ChildService,那此时需要在META-INF/services中放置文件com.test.Service,其中的内容就为该实现类的全限定名com.test.ChildService,有多个服务实现,每一行写一个服务实现,#后面的内容为注释,并且该文件只能够是以UTF-8编码。

    这种实现方式,感觉和我们通常的开发方式差不多,都是定义一个接口,然后子类实现父类中定义的方法,为什么要搞这么一套标准以及单独搞一个配置文件?这种方式主要是针对不同的服务提供厂商,对不同场景的提供不同的解决方案制定的一套标准,举个简单的例子,如现在的JDK中有支持音乐播放,假设只支持mp3的播放,有些厂商想在这个基础之上支持mp4的播放,有的想支持mp5,而这些厂商都是第三方厂商,如果没有提供SPI这种实现标准,那就只有修改JAVA的源代码了,那这个弊端也是显而易见的,也就是不能够随着JDK的升级而升级现在的应用了,而有了SPI标准,SUN公司只需要提供一个播放接口,在实现播放的功能上通过ServiceLoad的方式加载服务,那么第三方只需要实现这个播放接口,再按SPI标准进行打包成jar,再放到classpath下面就OK了,没有一点代码的侵入性。

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


Java SPI(Service Provider Interface)简介

SPI 简介SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制。一个服务(Service)通常指的是已知的接口或者抽象类,服务提供方就是对这...
  • FX_SKY
  • FX_SKY
  • 2016年07月17日 21:15
  • 2022

Java的Service Provider Interface(SPI)

SPI是Java 1.5新添加的一个内置标准,允许不同的开发者去实现某个特定的服务。 一个​Service就是一套著名的接口或抽象类,而Service Provider是这个Service的一个特定...
  • woxueliuyun
  • woxueliuyun
  • 2014年01月09日 22:16
  • 3141

JSR 196: Java Authentication Service Provider Interface for Containers

JSR 196规范——Java身份认证服务提供器(Authentication Service Provider,简称ASP)容器接口界面。规范中定义了一个标准的服务提供器接口界面,综合了容器与验证机...
  • teamlet
  • teamlet
  • 2007年02月13日 13:48
  • 1823

Java中的SPI(Service Provider Interface)

SPI(Service Provider Interface),一个Java内置的标准,允许不同的开发者去实现某个特定的服务。 A service is a well-known set of ...
  • baohuan_love
  • baohuan_love
  • 2013年11月05日 12:45
  • 949

SPI(service provider interface 服务提供者接口)

SPI 平时写代码一般不会用到,但是到了做一些基础组件开发或者是中间件开发的时候,SPI 是一个必须要掌握的知识点......
  • wenniuwuren
  • wenniuwuren
  • 2017年02月14日 16:22
  • 450

jdk service provider interface

SPI 简介 SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制。 目前有不少框架用它来做服务的扩展发现, 简单来说,它就是一种动态替换发...
  • youlianying
  • youlianying
  • 2014年09月01日 11:00
  • 1779

服务提供者框架(Service Provider FrameWork)——jdbc连接

服务提供者框架组建: Service Interface  具体的业务逻辑实现 的协议,各大业内厂商根据自己的业务逻辑实现。Service Provider Interface "负责创建其服务...
  • lemon89
  • lemon89
  • 2015年04月18日 12:42
  • 901

Java的SPI(Service Provider Interface)规范

Java的SPI(Service Provider Interface)规范:规范内容当服务的提供者,提供了服务接口的一种实现之后,在jar包的META-INF/services/目录里同时创建一个以...
  • LiPanGeng
  • LiPanGeng
  • 2016年05月23日 12:38
  • 461

SPI (Service Provider Interface)

SPI (Service Provider Interface)
  • Tao_QQ
  • Tao_QQ
  • 2015年12月21日 22:01
  • 468

Developing a Service Provider using Java API(Service Provider Interface)

这篇关于SPI的文章是在blogspot上面,被ZF给强奸了,大多数人访问不了,就贴在这里,比较好懂。 From ServiceLoader javadoc: A service is a we...
  • fenglibing
  • fenglibing
  • 2011年12月19日 11:23
  • 5586
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java Service Provider Interface 简单示例
举报原因:
原因补充:

(最多只允许输入30个字)