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();
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章