Java - SPI机制

news/2024/7/7 23:58:53

本文参考:SPI机制

SPI(Service Provider Interface),是JDK内置的一种服务提供发现机制,可以用来启动框架扩展和替换组件,主要是被框架的开发人员使用,比如 java.sql.Driver接口,其他不同厂商可以针对统一接口做出不同的实现,MySQL和PostgreSQL都有不同的实现提供给用户,而 Java 的SPI机制可以为某个接口寻找服务发现。Java中SPI机制主要思想是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要,其核心思想就是解耦。

在这里插入图片描述

当程序的提供者提供了一种接口的实现之后,需要在classPath下的 META-INF/services/ 目录中创建一个以服务接口命名的文件,这个文件里的内容就是这个接口的具体的实现类。当其他的程序需要这个服务的时候,就可以通过查找这个jar包(一般都是以jar包做依赖)的META-INF/services/ 中的配置文件,配置文件中有接口的具体的实现类名,可以根据这个类名进行加载实例化,就可以使用该服务了。JDK中查找服务的实现的工具类是:java.util.ServiceLoader

SPI机制的应用?

  • SPI机制 - JDBC DriverManager

    在JDBC4.0之前,在开发有连接数据库的时候,通常会用 Class.forName(“com.mysql.jdbc.Driver”) 这句先加载数据库相关的驱动,然后再进行获取连接等的操作。而JDBC4.0之后不需要用 Class.forName(“com.mysql.jdbc.Driver”) 来加载驱动,直接获取连接就可以了,现在这种方式就是使用了 Java的SPI扩展机制来实现。

  • JDBC接口定义

    首先在 Java中定义了接口 java.sql.Driver,但是并没有具体的实现,具体的实现都是由不同厂商来提供的

  • MySQL实现

在 MySQL的 jar包 mysql-connector-java:8.0.22 中,可以找到 META-INF/services/ 目录,该目录下会有一个名字为 java.sql.Driver的文件,文件内容是 com.mysql.cj.jdbc.Driver ,这里面的内容就是针对 Java中定义的接口的实现。

下面测试一个 demo:

定义一个存储方式接口 SPIStoreInterface
/**
 * SPI interface
 */
public interface SPIStoreInterface {

    String storeMethod(String method);
}
编写两个实现类 CloudStore、LocalStore

CloudStore:

/**
 * use Network store method
 */
public class CloudStore implements SPIStoreInterface {

    private static final Logger LOG = LoggerFactory.getLogger(CloudStore.class);

    @Override
    public String storeMethod(String method) {
        LOG.info("使用云存储");
        return "network store";
    }
}

LocalStore:

/**
 * use Local store method
 */
public class LocalStore implements SPIStoreInterface {

    private static final Logger LOG = LoggerFactory.getLogger(LocalStore.class);

    @Override
    public String storeMethod(String method) {
        LOG.info("使用本地存储");
        return "network store";
    }
}
编写SPI services文件

在这里插入图片描述

进行测试,验证效果
public class TestSPI {
    public static void main(String[] args) {
        ServiceLoader<SPIStoreInterface> loader = ServiceLoader.load(SPIStoreInterface.class);
        Iterator<SPIStoreInterface> iterator = loader.iterator();
        while (iterator.hasNext()) {
            SPIStoreInterface next = iterator.next();
            next.storeMethod("spi test success");
        }
    }
}

result:
在这里插入图片描述


http://lihuaxi.xjx100.cn/news/2032190.html

相关文章

【Java EE初阶十二】网络原理(二)

2. 传输层 2.2 TCP协议 2.2.2 关于可靠传输 4.滑动窗口 前面的三个机制&#xff0c;都是在保证 tcp 的可靠性&#xff1b; TCP 的可靠传输,是会影响传输的效率的.(多出了一些等待 ack 的时间,单位时间内能传输的数据就少了)&#xff1b; 滑动窗口,就让可靠传输对性能的影响,更…

【JavaScript】深浅拷贝

JavaScript中复制对象有深拷贝和浅拷贝两种方式 浅拷贝:浅拷贝只复制对象的第一层属性,而不复制嵌套对象的引用。这意味着如果原始对象包含嵌套对象,浅拷贝后的对象仍然会共享这些嵌套对象的引用。可以使用`Object.assign()`或展开运算符(`...`)来进行浅拷贝。 // 浅拷贝示…

RegExp正则表达式左限定右限定左右限定,预查询,预查寻,断言 : (?<= , (?= , (?<! , (?!

RegExp正则表达式左限定右限定左右限定,预查询,预查寻,断言 : (?< , (? , (?<! , (?! 有好多种称呼 (?< , (? , (?<! , (?! 有好多种称呼 , 我称为: 左限定, 右限定, 左否定, 右否定 (?<左限定)    (?右限定)(?<!左否定)    (?!右限定) 再…

spring boot3登录开发-1(整合jwt)

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 &#x1f30a;山高路远&#xff0c;行路漫漫&#xff0c;终有归途。 目录 前置条件 jwt简介 导依赖 编写jwt工具类 1.配置项直接嵌入代码&#xff0c;通过类名.静态方法使用 2.配置项写到…

【leetcode热题】二叉树的锯齿形层次遍历

难度&#xff1a; 中等通过率&#xff1a; 39.6%题目链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 题目描述 给定一个二叉树&#xff0c;返回其节点值的锯齿形层次遍历。&#xff08;即先从左往右&#xff0c;再从右往左进行下一层…

大数据01-导论

零、文章目录 大数据01-导论 1、数据与数据分析 **数据&#xff1a;是事实或观察的结果&#xff0c;是对客观事物的逻辑归纳&#xff0c;是用于表示客观事物的未经加工的原始素材。**数据可以是连续的值&#xff0c;比如声音、图像&#xff0c;称为模拟数据&#xff1b;也可…

火绒(显示病毒HEUR:Trojan/AvKiller.c),误删explore.exe,导致电脑白屏,解决方法

桌面程序explore.exe被火绒当病毒清理了 对&#xff0c;就是火绒导致的&#xff0c;如果按照操作依然黑/白屏&#xff0c;直接找到火绒安装目录打开火绒在右上角设置区找到隔离区里把explorer全部恢复&#xff0c;然后根据提示加到白名单&#xff0c;最后关闭程序后重启或者直接…

清除Django的管理员admin站点中“Recent Actions“最近活动面板上的所有信息

清除Django的管理员admin站点中"Recent Actions"最近活动面板上的所有信息 本文主要介绍了如何清除Django的管理员admin站点中"Recent Actions"最近活动面板上的所有信息 操作步骤如下 进入Django项目目录中运行代python manage.py shell进入Django shell…