Java-深入理解ServiceLoader类与SPI机制

本文深入探讨Java的ServiceLoader类和SPI(Service Provider Interface)机制,通过一个使用案例介绍了SPI如何动态发现和加载接口实现。文章详细解析了ServiceLoader的内部实现逻辑,包括构造方法、迭代器的工作原理,并对其效率和设计模式进行了总结和评价。
摘要由CSDN通过智能技术生成

Java-ServiceLoader类与SPI机制

引子

对于Java中的Service类和SPI机制的透彻理解,也算是对Java类加载模型的掌握的不错的一个反映。

了解一个不太熟悉的类,那么从使用案例出发,读懂源代码以及代码内部执行逻辑是一个不错的学习方式。


一、使用案例

通常情况下,使用ServiceLoader来实现SPI机制。 SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制。SPI是一种动态替换发现的机制, 比如有个接口,想运行时动态的给它添加实现,你只需要添加一个实现。

SPI机制可以归纳为如下的图:

SPI_Model
起始这样说起来还是比较抽象,那么下面举一个具体的例子,案例为JDBC的调用例子:

案例如下:

logicByFisherman
JDBC中的接口即为:java.sql.Driver

SPI机制的实现核心类为:java.util.ServiceLoader

Provider则为:com.mysql.jdbc.Driver

外层调用则是我们进行增删改查JDBC操作所在的代码块,但是对于那些现在还没有学过JDBC的小伙伴来说(不难学~),这可能会有点难理理解,所以我这里就举一个使用案例:

按照上图的SPI执行逻辑,我们需要写一个接口、至少一个接口的实现类、以及外层调用的测试类。

但是要求以这样的目录书结构来定义项目文件,否则SPI机制无法实现(类加载机制相关,之后会讲):

E:.
│  MyTest.java
│
├─com
│  └─fisherman
│      └─spi
│          │  HelloInterface.java
│          │
│          └─impl
│                  HelloJava.java
│                  HelloWorld.java
│
└─META-INF
    └─services
            com.fisherman.spi.HelloInterface

其中:

  1. MyTest.java为测试java文件,负责外层调用;
  2. HelloInterface.java为接口文件,等待其他类将其实现;
  3. HelloJava.java 以及 HelloWorld.java 为接口的实现类;
  4. META-INF
    └─services
    com.fisherman.spi.HelloInterface 为配置文件,负责类加载过程中的路径值。

首先给出接口的逻辑:

public interface HelloInterface {
   
    void sayHello();
}

其次,两个实现类的代码:

public class HelloJava implements HelloInterface {
   
    @Override
    public void sayHello() {
   
        System.out.println("HelloJava.");
    }
}
public class HelloWorld implements HelloInterface {
   
    @Override
    public void sayHello() {
   
        System.out.println("HelloWorld.");
    }
}

然后,配置文件:com.fisherman.spi.HelloInterface

com.fisherman.spi.impl.HelloWorld
com.fisherman.spi.impl.HelloJava

最后测试文件:

public class MyTest26 {
   

    public static void main(String[] args) {
   

        ServiceLoader<HelloInterface> loaders = ServiceLoader.load(HelloInterface.class);
        
        for (HelloInterface in : loaders) {
   
            in.sayHello();
        }
        
    }

}

测试文件运行后的控制台输出:

HelloWorld.
HelloJava.

我们从控制台的打印信息可知我们成功地实现了SPI机制,通过 ServiceLoader 类实现了等待实现的接口和实现其接口的类之间的联

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值