配置JDK SPI失败,竟如此简单问题都解决不了?

2026-05-25 05:561阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1395个文字,预计阅读时间需要6分钟。

配置JDK SPI失败,竟如此简单问题都解决不了?

今天去幼儿园接小侄女,路上聊起天。小侄女说:小叔,今天我吃的东西被老师发现了+我:老师说了什么+小侄女:她说拿出去,跟小朋友一起分享+我:那你拿出来了没+小侄女:我拿出来了,跟小朋友一起吃了。

开心一刻

  今天去幼儿园接小侄女,路上聊起了天

  小侄女:小叔,今天我吃东西被老师发现了

  我:老师说了什么

  小侄女:她说拿出来,跟小朋友一起分享

  我:那你拿出来了吗

  小侄女一脸可怜的看向我,说道:没有,我没有那么多鼻屎

SPI   概念

  SPI 全称Service Provider Interface,直译过来就是:服务提供接口,是不是有点抽象?

  简单点理解,Java SPI 就是提供这样的一个机制:为某个接口寻找服务实现的机制

  还是抽象?我们往下看它的具体实现就好理解了

  实现三板斧

  1、接口与实现

    Animal 接口

    Dog 实现

    Cat 实现

  2、配置文件

    配置文件有点讲究,需要按这套规则来

    2.1 在src/main/resources/下建立目录:/META-INF/services,位置和名字都必须严格按这个来,一字都不能差

    2.2 在/META-INF/services目录下创建一个以接口全限定类名为名的文件:com.qsl.service.Animal,没有额外的后缀

    2.3 将接口实现类的全限定类名写入到 2.2 创建的文件中,一个实现占一行

  3、ServiceLoader 加载

    通过ServiceLoader进行加载,代码很简单,如下所示

    正常情况下会输出如下内容

  示例工程结构如下

  至此,对SPI的感觉是不是没那么抽象了

  简单理解,Java SPI是基于接口的编程+策略模式+配置文件实现的动态加载机制

  使用场景

  不太好概括,一千个人眼中有一千个哈姆雷特

  但是我们可以通过一些案例来形成自己的概括

  1、DriverManager

    不知道大家还记得JDBC的写法吗

    我们去跟下DriverManager的源码

配置JDK SPI失败,竟如此简单问题都解决不了?

    我们再看下MySQL驱动的包结构

  2、SLF4J

    具体源码我就不带大家去跟了,有兴趣的可以去看看:从源码来理解slf4j的绑定,以及logback对配置文件的加载 中的问题1

  3、Spring SPI

    Spring有自己的SPI实现机制,和JDK SPI略有不同

    Spring是在src/main/resources/META-INF目录下创建spring.factories,里面以键值对的方式存放多个实现,类似如下

  4、Dubbo SPI

    Dubbo又有自己的一套实现,配置文件需要放到META-INF/dubbo目录下

    具体细节可查看其官方文档:Dubbo SPI

问题重现

  此刻,大家是不是觉得JDK SPI很简单?

  但正是这么简单的东西,楼主都碰到了问题,如下图所示

  当时人就懵了!!!

问题排查

  一度怀疑是不是JDK SPI还有额外的配置

  因为是工作中的项目出了这个问题,所以我自建了一个demo来验证实现三板斧

  结果demo的执行是没问题的,这也就说明JDK SPI的实现就只有那三板斧,那问题出在哪了?

  本着快速解决问题的目的,我换了一种实现方式,采用Spring SPI

  结果依然是有问题,同样是读不到spring.factories中的配置

  正在一筹莫展之际,直觉告诉我是不是maven构建出了问题,所以我对项目进行了package,然后去看了下打好的包的目录结构

  META-INF目录下的com.qsl.service.Animal文件了?

  肯定是pom.xml配置不对

  我是万万没想到pom.xml会进行如上的配置(后面问了老同事,没特别的原因,就是简单的认为只会有 xml 和 yml 配置文件)

  此刻,相信大家都知道怎么改了吧(去掉<includes>标签,或者在<includes>中加上)

  然而楼主没用采用上述两种方案的任一一个,也没有改pom.xml,就问你气不气?

总结

  1、JDK SPI的使用,就那三板斧,如果出了问题,不用想,肯定不是JDK SPI的问题

  2、关于SPI的使用场景,楼主仍然不做概括(太菜,概括不好),大家自行去概括

  3、关于pom.xml

    楼主之前写过一篇:Maven pom.xml中的元素modules、parent、properties以及import

    但就是没讲<build>,下次补上,你们记得提醒我哦!

本文共计1395个文字,预计阅读时间需要6分钟。

配置JDK SPI失败,竟如此简单问题都解决不了?

今天去幼儿园接小侄女,路上聊起天。小侄女说:小叔,今天我吃的东西被老师发现了+我:老师说了什么+小侄女:她说拿出去,跟小朋友一起分享+我:那你拿出来了没+小侄女:我拿出来了,跟小朋友一起吃了。

开心一刻

  今天去幼儿园接小侄女,路上聊起了天

  小侄女:小叔,今天我吃东西被老师发现了

  我:老师说了什么

  小侄女:她说拿出来,跟小朋友一起分享

  我:那你拿出来了吗

  小侄女一脸可怜的看向我,说道:没有,我没有那么多鼻屎

SPI   概念

  SPI 全称Service Provider Interface,直译过来就是:服务提供接口,是不是有点抽象?

  简单点理解,Java SPI 就是提供这样的一个机制:为某个接口寻找服务实现的机制

  还是抽象?我们往下看它的具体实现就好理解了

  实现三板斧

  1、接口与实现

    Animal 接口

    Dog 实现

    Cat 实现

  2、配置文件

    配置文件有点讲究,需要按这套规则来

    2.1 在src/main/resources/下建立目录:/META-INF/services,位置和名字都必须严格按这个来,一字都不能差

    2.2 在/META-INF/services目录下创建一个以接口全限定类名为名的文件:com.qsl.service.Animal,没有额外的后缀

    2.3 将接口实现类的全限定类名写入到 2.2 创建的文件中,一个实现占一行

  3、ServiceLoader 加载

    通过ServiceLoader进行加载,代码很简单,如下所示

    正常情况下会输出如下内容

  示例工程结构如下

  至此,对SPI的感觉是不是没那么抽象了

  简单理解,Java SPI是基于接口的编程+策略模式+配置文件实现的动态加载机制

  使用场景

  不太好概括,一千个人眼中有一千个哈姆雷特

  但是我们可以通过一些案例来形成自己的概括

  1、DriverManager

    不知道大家还记得JDBC的写法吗

    我们去跟下DriverManager的源码

配置JDK SPI失败,竟如此简单问题都解决不了?

    我们再看下MySQL驱动的包结构

  2、SLF4J

    具体源码我就不带大家去跟了,有兴趣的可以去看看:从源码来理解slf4j的绑定,以及logback对配置文件的加载 中的问题1

  3、Spring SPI

    Spring有自己的SPI实现机制,和JDK SPI略有不同

    Spring是在src/main/resources/META-INF目录下创建spring.factories,里面以键值对的方式存放多个实现,类似如下

  4、Dubbo SPI

    Dubbo又有自己的一套实现,配置文件需要放到META-INF/dubbo目录下

    具体细节可查看其官方文档:Dubbo SPI

问题重现

  此刻,大家是不是觉得JDK SPI很简单?

  但正是这么简单的东西,楼主都碰到了问题,如下图所示

  当时人就懵了!!!

问题排查

  一度怀疑是不是JDK SPI还有额外的配置

  因为是工作中的项目出了这个问题,所以我自建了一个demo来验证实现三板斧

  结果demo的执行是没问题的,这也就说明JDK SPI的实现就只有那三板斧,那问题出在哪了?

  本着快速解决问题的目的,我换了一种实现方式,采用Spring SPI

  结果依然是有问题,同样是读不到spring.factories中的配置

  正在一筹莫展之际,直觉告诉我是不是maven构建出了问题,所以我对项目进行了package,然后去看了下打好的包的目录结构

  META-INF目录下的com.qsl.service.Animal文件了?

  肯定是pom.xml配置不对

  我是万万没想到pom.xml会进行如上的配置(后面问了老同事,没特别的原因,就是简单的认为只会有 xml 和 yml 配置文件)

  此刻,相信大家都知道怎么改了吧(去掉<includes>标签,或者在<includes>中加上)

  然而楼主没用采用上述两种方案的任一一个,也没有改pom.xml,就问你气不气?

总结

  1、JDK SPI的使用,就那三板斧,如果出了问题,不用想,肯定不是JDK SPI的问题

  2、关于SPI的使用场景,楼主仍然不做概括(太菜,概括不好),大家自行去概括

  3、关于pom.xml

    楼主之前写过一篇:Maven pom.xml中的元素modules、parent、properties以及import

    但就是没讲<build>,下次补上,你们记得提醒我哦!