1.概述

jdk6中引入了一个新特性,使得我们可以根据一个指定的「接口」去找到并加载指定的「实现」。
本篇文章会详细介绍下SPI的用法及场景。

2.关键组成

java.sql.Driver为例

Service

一个众所周知的「接口」。比如说jdk包中的java.sql.Driver,,这就是JDBC的接口定义。它没有具体的实现,具体的实现由不同的厂商自己提供,例如MySQL的com.mysql.jdbc.Driver、Oracle的oracle.jdbc.driver.OracleDriver

Service Provider

SPI 的特定实现。服务提供者包含一个或多个实现或扩展服务类型的具体类。

服务提供者通过配置文件进行配置和标识,将该文件放在资源目录 META-INF/services 中。文件名是 SPI 的完全限定名,其内容是 SPI 实现的完全限定名。

Service Provider 是一个 jar 文件,我们将其放置在应用程序类路径、 Java 扩展类路径或用户定义的类路径中。

来看下mysql-connector-java是怎么做的

可以看到Driver继承了NonRegisteringDriver并且实现了jdk提供的java.sql.Driver接口。NonRegisteringDriver本身也实现了jdk提供的java.sql.Driver接口。

Driver中的静态域部分只做了一件事情,那就看下DriverManager是什么。

DriverManagerjava.sql.Driver接口一样,也是JDK提供的。从命名就可以看出,这个类的作用就是管理所有能加载到的java.sql.Driver接口实现。

DriverManager中有这么一段代码:

static {loadInitialDrivers();println("JDBC DriverManager initialized");
}

loadInitialDrivers()的实现中比较长,截取一段我们关注的

ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
Iterator<Driver> driversIterator = loadedDrivers.iterator();

总结

  1. JDK提供了JDBCjava.sql.Driver接口
  2. mysql提供对java.sql.Driver的实现com.mysql.jdbc.Driver
  3. mysqlcom.mysql.jdbc.Driver被实例化时,使用JDK提供的DriverManager做注册
  4. DriverManager实例化时,通过JDKServiceLoader扫描、加载java.sql.Driver的实现类

ServiceLoader

SPI 的核心是 ServiceLoader 类。
它具有延迟发现和加载实现的作用。
它使用上下文类路径来定位Service Provider的实现并将它们放入内部缓存中。

其代码中定义了扫描包的路径:

private static final String PREFIX = "META-INF/services/";

3.打破双亲委派

我们知道jdk的核心API(e.g rt.jar)是BootstrapClassLoader加载的,三方提供的jar包是AppClassLoader加载的,那么ServiceLoader是rt.jar中的类,那么对应的加载器就是BootstrapClassLoader

那么问题来了。

如果一个类由类加载器加载,那么这个类依赖的类也是由相同的类加载器加载的。

很显然,ServiceLoader这里打破了双亲委派机制
涉及到源码实现较多,和本篇主题关系不大,留到下篇文章再研究。

下班!

SPI : Service Provider Interface相关推荐

  1. Java中的SPI(Service Provider Interface介绍及示例

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 一个服务 ...

  2. Java基础学习总结(145)——Java SPI(Service Provider Interface)简介

    SPI 简介 SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制.一个服务(Service)通常指的是已知的接口或者抽象类,服务提供方就是对 ...

  3. SPI(Service Provider Interface)详解

    介绍 SPI 全称为 (Service Provider Interface) ,是JVM内置的一种服务提供发现机制.Java在语言层面为我们提供了一种方便地创建可扩展应用的途径.我们只需要按照SPI ...

  4. java provider_Java SPI(Service Provider Interface)

    //ServiceLoader实现了Iterable接口,可以遍历所有的服务实现者 public final class ServiceLoader implements Iterable{//查找配 ...

  5. SPI(Service Provider Interface)

    ServiceLoad中的spi 1.简介 JDK1.6引入的特性,用来实现SPI(Service Provider Interface),一种服务发现机制. 2.JDBC举例 2.1.引入mysql ...

  6. Service Provider Interface(SPI)

    目录 1.什么是SPI 2.SPI的使用 3.源码分析: 4.应用 1.什么是SPI SPI全称Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的接口 ...

  7. LSP(Layered Service Provider)入门的基础知识概念

    1.套接字 TCP用主机的IP地址加上主机上的端口号作为TCP连接的端点,这种端点就叫做套接字(socket)或插口. 套接字用(IP地址:端口号)表示. 它是网络通信过程中端点的抽象表示,包含进行网 ...

  8. Writing a Winsock 2 Layered Service Provider

    Wei Hua, Jim Ohlund, Barry Butterklee 著 来源:http://greatdong.blog.edu.cn 作者:董岩 译 greatdong_2001@163.c ...

  9. Introduction to the Service Provider Interfaces--官方文档

    地址:https://docs.oracle.com/javase/tutorial/sound/SPI-intro.html What Are Services? Services are unit ...

最新文章

  1. Android中View(视图)绘制不同状态背景图片原理深入分析以及StateListDrawable使用详解...
  2. 【文本信息抽取与结构化】详聊如何用BERT实现关系抽取
  3. 发动机异响故障诊断与排除_发动机缺缸故障诊断以及排除方法
  4. 建立时间、保持时间与亚稳态
  5. go语言 函数相关1:实参到形参的传递永远是值拷贝
  6. [Scrum] 12.22
  7. 线程的故事:3 位“母亲”成就了优秀的我!
  8. PAT 乙级 1044. 火星数字(20) Java版
  9. 在线JSON美化格式化工具
  10. 在代码中加载storyBoard中的ViewController
  11. Tips of keras
  12. linux跟踪线程,linux跟踪线程的方法:LWP和strace命令
  13. idm chrome扩展被阻止解决办法
  14. 一键圣诞帽 html5源码,HTML5在线教程之微信小程序“圣诞帽”的实现思路详解
  15. React 中 TypeScript 和装饰器及 Hooks
  16. 【视频】开发工具第12期:鸿蒙智联新交互体验实践分享(二)
  17. cmaq安装教程linux,CMAQ编译和安装
  18. 大数据入门--Flink(四)状态管理与容错机制
  19. 打印机原理及安装,下载驱动
  20. 湘大计算机学校聚会,计算机学院计算机专业96级2班校友举行入校20周年返校聚会...

热门文章

  1. 浅谈什么是前端SEO
  2. 【转载】Chrome插件在高版本浏览器中安装报错解决
  3. 汽车结构件疲劳耐久开发
  4. 抗疫先锋 | 普元信息为疫情防控提供领先的应用开发服务及数据管理支持
  5. c++ 编一程序,输入一行字符串,将其中的大写英文字母改为小写,再输出。
  6. Win10 2004 WSL2 ERROR: 0x800701bc
  7. 净零排放承诺:能把我们带到想要去的地方吗?
  8. 计算机网络中校园网的不利是什么意思,【这是什么意思?】校园网问题~
  9. PS使用羽化制作简单的羽化特效
  10. python fillna_python – fillna对面的熊猫(0)