1. 程式人生 > 實用技巧 >Java SPI 機制

Java SPI 機制

SPIService Provider Interface)服務提供發現介面。

不同於微服務中的服務發現,其本質是典型的面向介面程式設計,也就是解耦。

同時SPI使用的是一種 ”外掛思維“,即服務提供者負責服務所有的維護,當替換服務提供方時不需要呼叫方修改程式碼及配置檔案。

組成:

  服務:指介面和抽象類的集合。由服務呼叫方提供

  服務提供者:是服務的特定實現

    服務提供者可以以擴充套件的形式安裝在Java平臺的實現中,也就是將 jar檔案放入任意常用的擴充套件目錄中。也可通過將提供者加入應用程式類路徑路徑,或者通過其他某些特定於平臺的方式使其可用。

SPI規範:

1、在資源目錄resource/META-INF/services

中放置提供者配置檔案 來標識服務提供者。檔名稱是服務型別(介面)的全限定名(最終會通過這裡的全限定名來反射建立物件)。

2、該檔案包含一個具體提供者類的全限定名,每行一個。忽略各名稱周圍的空格、製表符和空行。可以使用 ‘#’標註註釋。

3、該檔案必須使用UTF-8編碼

服務載入器:

java.util.ServiceLoader<S>

  JDK官方提供的SPI機制下的服務載入器,S:要被此載入器載入的服務型別

返回 方法名 描述
Iterator<S> iterator() 以延遲方式載入此載入器服務的可用提供者。
static <S> ServiceLoader<S> load(Class<S> service) 針對給定服務型別建立新的服務載入器,使用當前執行緒的上下文類載入器。
static <S> ServiceLoader<S> load(Class<S> service, ClassLoader loader) 針對給定服務型別和類載入器建立新的服務載入器。
static <S> ServiceLoader<S> loadInstalled(Class<S> service) 針對給定服務型別建立新的服務載入器,使用擴充套件類載入器。
void reload() 清除此載入器的服務者快取,以過載所有服務者。
String toString() 返回一個描述此服務的字串。

   
    

示例:

mysql-connector-java-5.1.47.jar為例

1、介面服務Driver,全限定名為:

  java.sql.Driver

2、服務配置

  在其jar包的META-INF/services/ 目錄下有個 java.sql.Driver 檔案,內容為:

    com.mysql.jdbc.Driver
    com.mysql.fabric.jdbc.FabricMySQLDriver

  

3、呼叫方使用ServiceLoader載入所有提供的服務 (java.sql.DriverManager中的static{loadInitialDrivers();})

  

DubboSPI:

  http://dubbo.apache.org/docs/v2.7/dev/spi/