Java SPI 機制
SPI(Service 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/