SPI:全称是Service Provider Interface,全称是服务提供者接口
它是从Java 6开始引入的,是一种基于ClassLoader来发现并加载服务的机制。
- Service
是一个公开的接口或抽象类,定义了一个抽象的功能模块。 - Service Provider
是Service接口的一个实现类。ServiceLoader - ServiceLoader
是SPI机制中的核心组件,负责在运行时发现并加载Service Provider。
ServiceLoader加载和发现Service Provider,而Service Provider是具体实现了Service接口
SPI原理我们拿JDBC举例:
JDBC的流程:
- 加载驱动
- 打开链接
- 执行语句
- 处理结果集
- 关闭连接
其中我们关注加载驱动的环节,我们是使用Class.forName()加载驱动的。JDBC要求Driver实现类在类加载的时候,能将自身的实例对象自动注册到DriverManager 中,从而加载数据库驱动。
有了SPI,程序员不用在更换驱动名,只需要引入相应的JAR包即可;
规范的配置文件:
- 文件路径:必须在JAR包中META-INF/services目录下
- 文件名称: Service接口的全限定名
- 文件内容:Service 实现类的全限定名。如果有多个实现类,那么每一个实现类在文件中单独占据一行
Service Provider类必须具备无参的默认构造方法:
- Service接口的实现类,即Service Provider类,必须具备无参的默认构造方法。因为随后通过反射技术实例化它时,是不带参数的。
保证能加载到配置文件和Service Provider类:
- 方式一:将Service Provider的JAR包放到classpath中(最常用,我们直接使用maven)
- 方式二:将JAR包安装到JRE的扩展目录中
- 方式三:自定义一个ClassLoader
- 作用:提供了一种组件发现和注册的方式,可以用于实现各种插件,或者灵活替换框架所使用的组件。
- 优点:基于面向接口编程,优雅地实现模块之间的解耦。
- 设计思想:面向接口+配置文件+反射技术
- 应用场景:JDBC · SLF4J . Servlet容器初始化·等等…
源码连接:https://gitee.com/yuehewei/java-spi.git
学习该播主:https://www.bilibili.com/video/BV1RY4y1v7mN
只是对视频整理的笔记;



