SPI 简介

SPI 全称为(Service Provider Interface),是JDK内置的一种服务提供发现机制。

一个服务(Service)通常指的是已知的接口或者抽象类,服务提供方就是对这个接口或者抽象类的实现,然后按照SPI 标准存放到资源路径(resources)META-INF/services目录下,文件的命名为该服务接口的全限定名。如有一个服务接口:

package com.winner.spi;

/**
* @author winner_0715
* @date 2018/4/1
*/
public interface DemoService {
String sayHello(String name);
}

其服务实现类为:

package com.winner.spi.impl;

import com.winner.spi.DemoService;

/**
* @author winner_0715
* @date 2018/4/1
*/
public class DemoServiceImpl implements DemoService { @Override
public String sayHello(String name) {
return "hello , " + name;
}
}

那此时需要在META-INF/services中创建一个名为com.ricky.codelab.spi.DemoService的文件,其中的内容就为该实现类的全限定名:com.ricky.codelab.spi.impl.DemoServiceImpl。 
如果该Service有多个服务实现,则每一行写一个服务实现(#后面的内容为注释),并且该文件只能够是以UTF-8编码。

然后,我们可以通过ServiceLoader.load(Class class); 来动态加载Service的实现类了。

许多开发框架都使用了Java的SPI机制,如java.sql.Driver的SPI实现(mysql驱动、oracle驱动等)、common-logging的日志接口实现、dubbo的扩展实现等等。

SPI机制的约定

  • 在META-INF/services/目录中创建以Service接口全限定名命名的文件,该文件内容为Service接口具体实现类的全限定名,文件编码必须为UTF-8。
  • 使用ServiceLoader.load(Class class); 动态加载Service接口的实现类。
  • 如SPI的实现类为jar,则需要将其放在当前程序的classpath下。
  • Service的具体实现类必须有一个不带参数的构造方法。

1、项目结构

2、Service接口定义

package com.winner.spi;

/**
* @author winner_0715
* @date 2018/4/1
*/
public interface DemoService {
String sayHello(String name);
}

3、Service接口实现类

本示例中DemoService有两个实现类,分别为:EnglishDemoServiceImpl和ChineseDemoServiceImpl,代码如下: 
EnglishDemoServiceImpl.java

package com.winner.spi.impl;

import com.winner.spi.DemoService;

/**
* @author winner_0715
* @date 2018/4/1
*/
public class EnglishDemoServiceImpl implements DemoService { @Override
public String sayHello(String name) {
return "hello , " + name;
}
}

ChineseDemoServiceImpl.java

package com.winner.spi.impl;

import com.winner.spi.DemoService;

/**
* @author winner_0715
* @date 2018/4/1
*/
public class ChineseDemoServiceImpl implements DemoService { @Override
public String sayHello(String name) {
return "你好 , " + name;
}
}

META-INF/services/配置

在src/main/resources 下创建META-INF/services/目录,并新建com.winner.spi.DemoService文件,内容如下:

#English implementation
com.winner.spi.impl.EnglishDemoServiceImpl
#Chinese implementation
com.winner.spi.impl.ChineseDemoServiceImpl

加载Service实现类

import com.winner.spi.DemoService;

import java.util.Iterator;
import java.util.ServiceLoader; /**
* @author winner_0715
* @date 2018/4/1
*/
public class Test {
public static void main(String[] args) {
ServiceLoader<DemoService> serviceLoader = ServiceLoader.load(DemoService.class);
Iterator<DemoService> it = serviceLoader.iterator();
while (it.hasNext()) {
DemoService demoService = it.next();
System.out.println("class:" + demoService.getClass().getName()
+ "-->" + demoService.sayHello("World"));
}
}
}

执行结果:

import com.winner.spi.DemoService;

import java.util.Iterator;
import java.util.ServiceLoader; /**
* @author winner_0715
* @date 2018/4/1
*/
public class Test {
public static void main(String[] args) {
ServiceLoader<DemoService> serviceLoader = ServiceLoader.load(DemoService.class);
Iterator<DemoService> it = serviceLoader.iterator();
while (it.hasNext()) {
DemoService demoService = it.next();
System.out.println("class:" + demoService.getClass().getName()
+ "-->" + demoService.sayHello("World"));
}
}
}

Java SPI(Service Provider Interface)简介的更多相关文章

  1. JAVA SPI(Service Provider Interface)原理、设计及源码解析(其一)

    背景 团队内部轮流技术分享,其他人都是分享源码,我每次都是设计和架构,感觉自己太特立独行.这次我要合群点,分享点源码. 概念 Service Provider Interface:服务提供方接口.是一 ...

  2. Java SPI(Service Provider Interface)

    SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制. 目前有不少框架用它来做服务的扩展发现, 简单来说,它就是一种动态替换发现的机制, 举个 ...

  3. java的spi(Service Provider Interface)机制及源码(java8)

    1.什么是java的spi spi 全称为 service provider interface 即 服务提供接口,用来作为服务的扩展发现.在运行时动态添加接口的实现,是对接口的实现类的创建管理. 2 ...

  4. SPI: Service Provider Interface

    Service Provider Interface: JDK提供的一种服务发现的机制:主要是用于厂商实现JDK的只用. 比如说打印机,JDK提供了一个驱动接口com.printl.printerDr ...

  5. Java中的SPI(Service Provider Interface)

    转自:http://singleant.iteye.com/blog/1497259 最近看到公司的一些框架和之前看到的开源的一些框架的一些服务发现和接入都采用了java的spi机制. 所以简单的总结 ...

  6. SPI(Service Provider Interface)机制

    JAVA SPI 约定如下:当服务的提供者提供了服务接口的一种实现之后,在jar包的META-INF/services/ 目录中同时创建一个以服务接口命名的文件,该文件中的内容就是实现该服务接口的具体 ...

  7. SPI(Service Provider Interface)--通过接口获取服务

    spi 现在已有实现 jdk 提供实现 dubbo里的spi实现 一.jdk实现 配置 定义接口 定义实现类 配置资源文件 classpath下创建(META-INF/services/接口全面:ME ...

  8. Service Provider Interface

    @(Java)[SPI] Service Provider Interface API的一种设计方法,一般用于一些服务提供给第三方实现或者扩展,可以增强框架的扩展或者替换一些组件. 结构 Servic ...

  9. 【Java实战】源码解析Java SPI(Service Provider Interface )机制原理

    一.背景知识 在阅读开源框架源码时,发现许多框架都支持SPI(Service Provider Interface ),前面有篇文章JDBC对Driver的加载时应用了SPI,参考[Hibernate ...

随机推荐

  1. 利用 ImageAI 在 COCO 上学习目标检测

    ImageAI是一个python库,旨在使开发人员能够使用简单的几行代码构建具有包含深度学习和计算机视觉功能的应用程序和系统. 这个 AI Commons 项目https://commons.spec ...

  2. 关于configure: error: no acceptable C compiler found in $PATH

    Linux系统在安装python3的时候报错: $ ./configure --prefix=/usr/local/python3 checking build system type... x86_ ...

  3. Vue之双向绑定原理动手记

    Vue.js的核心功能有两个:一是响应式的数据绑定系统,二是组件系统.本文是通过学习他人的文章,从而理解了双向绑定原理,从而在自己理解的基础上,自己动手实现数据的双向绑定. 目前几种主流的mvc(vm ...

  4. 那些年我们踩过的坑之表单reset

    开发者往往是在一个又一个的坑中成长起来的,自学的开发者尤其如此,刚刚填完一个坑,转身又掉进另一个坑.有些坑很容易就跳出来了,也有些坑能整了一天都没头绪,第二天早上一来发现后面就有一架通往坑外的梯子,坑 ...

  5. Java日期时间类

    日期时间类有三种: 一.java.util.Date:一般用于声明日期时间类型的变量. 二.java.sql.Date:一般用于数据库日期时间的映射. 三.java.util.Calendar:一般用 ...

  6. tornado登陆装饰器

    tornado作为鼎鼎大名的web异步框架,用来作为高性能服务器以及web框架都是首选.自从python3.4加入了asyncio原生协程后,tornado的最新版本也开始使用了原生的协程.定义协程函 ...

  7. android activity 启动模式

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 1,标准的, 2,单个 顶部 3,单个 任务 4,单个 实例 标准的 就是 每启动一次这 ...

  8. BZOJ.3673/3674.可持久化并查集(可持久化线段树 按秩合并/启发式合并)

    BZOJ 3673 BZOJ 3674(加强版) 如果每次操作最多只修改一个点的fa[],那么我们可以借助可持久化线段树来O(logn)做到.如果不考虑找fa[]的过程,时空复杂度都是O(logn). ...

  9. 关于Android4.X的Alertdialog对话框

    最近在做Android4.0的开发,发现AlertDialog相比较以前有了较大变化,就是在触摸对话框边缘外部,对话框消失 于是研究其父类发现,可以设置这么一条属性,当然必须先AlertDialog. ...

  10. 如何处理C++构造函数中的错误——兼谈不同语言的错误处理

    用C++写代码的时候总是避免不了处理错误,一般来说有两种方式,通过函数的返回值或者抛出异常.C语言的错误处理一律是通过函数的返回值来判断的,一般是返回0.NULL或者-1表示错误,或者直接返回错误代码 ...