Java - SPI机制

本文介绍了Java的SPI(ServiceProviderInterface)机制,如何通过元数据文件实现服务的自动加载,以及在JDBC中的应用示例,包括JDBC4.0后不再需要手动加载驱动。还展示了如何自定义接口并创建实现类,通过ServiceLoader进行动态加载。
摘要由CSDN通过智能技术生成

本文参考: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:
在这里插入图片描述

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值