java-spi 理解

JAVA - SPI理解

​ 先来看看我们平时使用的比较多的api:实现方提供了接口和实现,我们可以调用某些实现类的功能,实现方的接口和代码通常会放在一个包中

​ 那如果接口属于调用方时,我们就称为其为SPI,即一种为某个接口寻找服务实现的一种机制,举个简单的例子,jdbc连接数据库,第三方厂商根据一个统一的规范(jdbc.driver)实现各自的逻辑,所以当你使用jdbc的时候仅仅需要引入不同的第三方厂商的spi接口服务即可,Mysql的则是com.mysql.jdbc.Drive,Oracle则是oracle.jdbc.driver.OracleDriver。

在这里插入图片描述

spi的约定:

​ 当服务的提供者,提供了服务接口的一种实现之后,在jar包的META-INF/services/目录里同时创建一个以服务接口命名的文件,该文件里就是实现该服务接口的具体实现类。当外部程序装配这个模块的时候,就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入。

​ 基于这样的一个约定,就能很好的找到服务接口的实现类,而不需要在代码里指定,jdk提供服务实现类查找的工具类:java.util.ServiceLoader

SPI 简单示例:
  • 项目结构

在这里插入图片描述

-	spi-api 定义的接口,针对第三方厂商定义的统一规范,只有接口
-	spi-doctor 接口实现,即第三方厂商针对接口的不同实现之一
-	spi-teacher 接口实现,即第三方厂商针对接口的不同实现之一
-	spi-core 提供给用户使用的文件,用户使用的时候引入对应厂商的jar即可
  • api-spi
public interface PeopleAPI {
    public void profession();
}
  • spi-doctor

接口实现:

public class Doctor implements PeopleAPI {

    public void profession() {
        System.out.println("我是一名医生");
    }
}

在resource下新建目录META-INF/services,新建文件:com.PeopleAPI 写入具体的实现类名

com.test.Doctor

在这里插入图片描述

pom.xml

    <dependencies>
        <dependency>
            <groupId>z</groupId>
            <artifactId>spi-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
  • spi-teacher

类似spi-doctor一样的做法

public class Teacher implements PeopleAPI {

    public void profession() {
        System.out.println("我是一名老师");
    }
}

META-INF/services/com.PeopleAPI

com.test.Teacher

pom.xml

    <dependencies>
        <dependency>
            <groupId>z</groupId>
            <artifactId>spi-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
  • spi-core
public class PeopleCore {
    public  void getPeopleCore (){
        ServiceLoader<PeopleAPI> serviceLoader = ServiceLoader.load(PeopleAPI.class);
        Iterator<PeopleAPI> peoples = serviceLoader.iterator();
        boolean flag = true;
        while (peoples.hasNext()){
            flag = false;
            PeopleAPI peopleAPI = peoples.next();
            peopleAPI.profession();
        }
        if(flag){
            throw new RuntimeException("没找到具体实现类");
        }
    }

}

pom.xml

        <dependency>
            <groupId>z</groupId>
            <artifactId>spi-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>z</groupId>
            <artifactId>spi-teacher</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
 <!--    想用哪个只需要替换就可-->       
<!--        <dependency>-->
<!--            <groupId>z</groupId>-->
<!--            <artifactId>spi-doctor</artifactId>-->
<!--            <version>1.0-SNAPSHOT</version>-->
<!--        </dependency>-->

test

     @Test
    public void test1(){
        PeopleCore peopleCore = new PeopleCore();
        peopleCore.getPeopleCore();
    }
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值