开心一刻

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

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

  我:老师说了什么

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

  我:那你拿出来了吗

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

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 的源码

    我们再看下 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> ,下次补上,你们记得提醒我哦!

记一次 JDK SPI 配置不生效的问题 → 这么简单都不会,还是回家养猪吧的更多相关文章

  1. 记一次Linux修改MySQL配置不生效的问题

    背景 自己手上有一个项目服务用的是AWS EC2,最近从安全性和性能方面考虑,最近打算把腾讯云的MySQL数据库迁移到AWS RDS上,因为AWS的出口规则和安全组等问题,我需要修改默认的3306端口 ...

  2. Linux下安装java的jdk和配置环境变量

    每次感觉配这个超级简单 但是每次都要查下 记一下好了 Linux下安装jdk,步骤如下 1:下载jdk包:本章使用的为后缀为tar.gz的文件(不需要安装),如jdk-8u111-linux-x64. ...

  3. 新手上路Tomcat 7.x和JDK的配置

    前言:这段时间又复习了JAVA以前做东西总是在IDE里面好多基础的东西都不知道,这次买了本书让自己重新认识下JAVA! 说明:以前装JDK时,我是和Mars老师学的那种开发JAVA应用程序进行配置的环 ...

  4. JDK 安装环境配置(ubuntu)

    在Ubuntu 上安装jdk,先去官网下载相对应的tar包 网址:(这是jdk1.8) http://www.oracle.com/technetwork/java/javase/downloads/ ...

  5. linux 下安装jdk及配置jdk环境图解

    linux 下安装jdk及配置jdk环境图解 一:先检測是否已安装了JDK 运行命令: # rpm -qa|grep jdk  或   # rpm -q jdk  或  #find / -name j ...

  6. mac系统 安装 JDK 并配置环境

    第一步 : 下载 mac 版的 JDK 下载地址: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-213 ...

  7. Ubuntu 18.04安装JDK并配置环境变量

    1.官网下载jdk 下载链接 http://www.oracle.com/technetwork/java/javase/downloads/index.html 可以根据自己的系统进行下载 2.进行 ...

  8. linux安装jdk与配置-centos7版本

    1.Linux安裝jdk 1.如果電腦沒有wget命令的,先使用yum安裝wget命令. eg: yum install wget 2.安裝好后就可以直接使用wget命令去下載jdk. 附:打開官網連 ...

  9. Windows环境下JDK的配置及多版本JDK切换的方法记录

    (这里记录了笔者了解的关于JDK环境配置的信息,以及针对系统上存在不同版本JDK时所尝试的解决方案.具体来说,是已安装 JDK 8 后,又安装了 JDK 9 时所遇到的问题和尝试的解决方法.这次记录以 ...

随机推荐

  1. 前端每日实战:134# 视频演示如何用 CSS 和 GSAP 创作一个树枝发芽的 loader

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/LJmpXZ 可交互视频 此视频是可 ...

  2. PAT A1035 Password

    题目描述: To prepare for PAT, the judge sometimes has to generate random passwords for the users. The pr ...

  3. Java中重载的应用

    学习目标: 掌握Java方法的重载 学习内容: 1.重载定义 参数列表: 参数的类型 + 参数的个数 + 参数的顺序 方法签名: 方法名称 + 方法参数列表,在同一个类中,方法签名是唯一的,否则编译报 ...

  4. <!--[if IE]><style></style><![endif]-->

    CSS hack就是为了让你的CSS代码兼容不同的浏览器,其中最难对付的就是IE浏览器的兼容性,因为它的版本很多,不过还好,微软发表声明已经不对IE8以下的版本进行维护了.但是我们也不能就认为不用学I ...

  5. 常⽤的meta标签有哪些

    meta 标签由 name 和 content 属性定义,用来描述网页文档的属性,比如网页的作者,网页描述,关键词等,除了HTTP标准固定了一些name作为大家使用的共识,开发者还可以自定义name. ...

  6. 2021年3月-第02阶段-前端基础-HTML+CSS阶段-Day03

    HTML5 第三天 一. 认识 3D 转换 3D 的特点 近大远小 物体和面遮挡不可见 三维坐标系 x 轴:水平向右 -- 注意:x 轴右边是正值,左边是负值 y 轴:垂直向下 -- 注意:y 轴下面 ...

  7. 分布式应用运行时 Dapr 1.7 发布

    Dapr 是一个开源.可移植的.事件驱动的运行时,可以帮助开发人员构建在云和边缘上运行的弹性的.微服务的.无状态和有状态应用程序,并且关注于业务逻辑而不用考虑分布式相关的问题. 分布式相关的问题交给D ...

  8. Java-GUI编程之处理位图

    如果仅仅绘制一些简单的几何图形,程序的图形效果依然比较单调 . AWT 也允许在组件上绘制位图, Graphics 提供了 drawlmage() 方法用于绘制位图,该方法需要一个Image参数一一代 ...

  9. 用于激光雷达的 APD,SPAD 和 SiPM 分析

    1. 术语及定义 1.1 激光雷达,Light Detection And Range, LiDAR  发射激光光束,并接收回波以获取目标三维和/或速度信息的系统: 1.2 机械旋转激光雷达,Mech ...

  10. AcWing周赛43

    AcWing周赛43 题源:https://www.acwing.com/activity/content/1233/ 4314. 三元组 直接暴力做就是了,我一开始还在找规律..悲 我滴代码 #in ...