JAVA SPI 簡介
阿新 • • 發佈:2020-12-20
技術標籤:# SPI
JAVA SPI 簡介
SPI 是 Java 提供的一種服務載入方式,全名為 Service Provider Interface。根據 Java 的 SPI 規範,我們可以定義一個服務介面,具體的實現由對應的實現者去提供,即服務提供者。然後在使用的時候再根據 SPI 的規範去獲取對應的服務提供者的服務實現。通過 SPI 服務載入機制進行服務的註冊和發現,可以有效的避免在程式碼中將服務提供者寫死。從而可以基於介面程式設計,實現模組間的解耦。
SPI 機制的約定
- 在 META-INF/services/ 目錄中建立以介面全限定名命名的檔案,該檔案內容為API具體實現類的全限定名
- 使用 ServiceLoader 類動態載入 META-INF 中的實現類
- 如 SPI 的實現類為 Jar 則需要放在主程式 ClassPath 中
- 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 機制程式碼示例
package com.spi.test;
public interface People {
public String speak();
}
package com.spi.test;
public class Chinese implements People {
public String speak() {
return "你好,世界";
}
}
package com.spi.test; public class American implements People { public String speak() { return "Hello World"; } }
建立一個檔案,放置到 META-INF/Services 目錄:
檔名:com.spi.test.People
檔案內容:
com.spi.test.Chinese
com.spi.test.American
package com.spi.test;
import java.util.Iterator;
import java.util.ServiceLoader;
public class SpiTest {
public static void main(String[] args) {
ServiceLoader<People> peoples = ServiceLoader.load(People.class);
Iterator<People> iterator = peoples.iterator();
while (iterator.hasNext()) {
People people = iterator.next();
System.out.println(people.speak());
}
}
}
執行結果
你好,世界
Hello World