专栏首页朝雨忆轻尘Java SPI机制和使用示例

Java SPI机制和使用示例

JAVA SPI 简介

SPI 是 Java 提供的一种服务加载方式,全名为 Service Provider Interface。根据 Java 的 SPI 规范,我们可以定义一个服务接口,具体的实现由对应的实现者去提供,即服务提供者。然后在使用的时候再根据 SPI 的规范去获取对应的服务提供者的服务实现。通过 SPI 服务加载机制进行服务的注册和发现,可以有效的避免在代码中将服务提供者写死。从而可以基于接口编程,实现模块间的解耦。

SPI 机制的约定

1 在 META-INF/services/ 目录中创建以接口全限定名命名的文件,该文件内容为API具体实现类的全限定名

2 使用 ServiceLoader 类动态加载 META-INF 中的实现类

3 如 SPI 的实现类为 Jar 则需要放在主程序 ClassPath 中

4 API 具体实现类必须有一个不带参数的构造方法

SPI 应用场景举例

JDBC

jdbc4.0以前, 开发人员还需要基于Class.forName("xxx")的方式来装载驱动,jdbc4也基于spi的机制来发现驱动提供商了,可以通过METAINF/services/java.sql.Driver文件里指定实现类的方式来暴露驱动提供者.

COMMON-LOGGING

apache最早提供的日志的门面接口。只有接口,没有实现。具体方案由各提供商实现, 发现日志提供商是通过扫描METAINF/services/org.apache.commons.logging.LogFactory配置文件,通过读取该文件的内容找到日志提工商实现类。只要我们的日志实现里包含了这个文件,并在文件里制定 LogFactory工厂接口的实现类即可。

SPI 机制代码示例

接口 People.java

package org.louis.spi.test;

public interface People {

     public String speak();

}

实现类 Chinese.java

package org.louis.spi.test;
 
public class Chinese implements People{

    public String speak() {
 
        return "Chinese speak Chinese.";
 
    }
 
}

实现类 American.java

package org.louis.spi.test;
 
public class American implements People{

    public String speak() {
 
        return "American speak English.";
 
    }
 
}

创建一个文件,放置到 META-INF/Services 目录:

文件名:org.louis.spi.test.People

文件内容:

org.louis.spi.test.Chinese
org.louis.spi.test.American

新建一个测试工程,引入以上代码生成的Jar包

测试类SpiTest.java

package org.louis.test;
 
import java.util.Iterator;
import java.util.ServiceLoader;
 
import org.louis.spi.test.People;
import org.louis.spi.test.Chinese;
import org.louis.spi.test.American;
 
public class SpiTest {
    
    public static void main(String[] args) {
 
        ServiceLoader<People> peoples = ServiceLoader.load(People.class);
 
        Iterator<IOperation> iterator = peoples.iterator();
       while (iterator.hasNext()) {
 
            People people = iterator.next();
 
            System.out.println(people.speak());
 
        }
    } 
}

运行结果:

Chinese speak Chinese.

American speak English.

通过上面例子,我们看到,假如我要新加入一个韩国人的实现,那只需要新建一个新的工程,创建一个Koeran类实现People接口,并在自己工程 META-INF/Services 目录下放置一个配置文件指定Koeran实现类,将工程打成Jar包,就完成了一个新的服务实现的开发。


作者:朝雨忆轻尘 出处:https://www.cnblogs.com/xifengxiaoma/  版权所有,欢迎转载,转载请注明原文作者及出处。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Eclipse中Maven项目出现红色感叹号问题

    在Eclipse环境下,有时我们会遇到Maven项目出现红色感叹号的情形,而一旦项目出现感叹号,Eclipse便无法帮我们进行自动编译等工作,尽管有时候不会影响...

    朝雨忆轻尘
  • Spring Boot:使用Memcached缓存

    Memcached是一个自由开源的,高性能,分布式内存对象缓存系统。Memcached基于内存的key-value存储,用来存储小块的任意数据,这些数据可以是数...

    朝雨忆轻尘
  • Spring Boot:使用Redis存储技术

    Redis是一个开源免费的高性能key-value数据库,读取速度达110000次/s,写入速度达81000次/s。Redis支持丰富的数据类型,如Lists,...

    朝雨忆轻尘
  • 性能调优之MYSQL高并发优化

    一、数据库结构的设计 表的设计具体注意的问题: 1、数据行的长度不要超过8020字节,如果超过这个长度的话在物理页中这条数据会占用两行从而造成存储碎片,降低查询...

    wangxl
  • 让DeepLearning4j阅读小说并给出关联度最高的词

    DeepLearning4j是一个java的神经网络框架,便于java程序员使用神经网络来完成一些机器学习工程。

    天涯泪小武
  • Influx Sql系列教程七:delete 删除数据

    前面介绍了使用insert实现新增和修改记录的使用姿势,接下来我们看一下另外一个简单的使用方式,如何删除数据

    小灰灰
  • 更强免杀来袭!Cobaltstrike 3.14正式版破解(暗桩绕过)+汉化

    CS3.14 出来也很久了,新版很强,尤其是免杀,但是因为有暗桩,很多人没能正常使用,本文结合了圈子社区两篇精华文章,既为大家分享了干货,也剖析了暗桩的一些来龙...

    洛米唯熊
  • python | 读文件 | csv 、json、pickle、sql等

    来说下pandas用于读取的文件格式有那些吧,这些读取方法获取文件的速度超级快,很实用。

    努力在北京混出人样
  • 用GeoTools实现shp+sld导出图片

    lzugis
  • 论文实践学习 - Deep Metric Learning via Lifted Structured Feature Embedding

    利用 code/gen_splits.m 来创建 mat 格式的 train/test 数据集分割,主要修改的地方如下:

    AIHGF

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动