1. 程式人生 > 其它 >JAVA SPI 簡介

JAVA SPI 簡介

技術標籤:# SPI

JAVA SPI 簡介

SPI 是 Java 提供的一種服務載入方式,全名為 Service Provider Interface。根據 Java 的 SPI 規範,我們可以定義一個服務介面,具體的實現由對應的實現者去提供,即服務提供者。然後在使用的時候再根據 SPI 的規範去獲取對應的服務提供者的服務實現。通過 SPI 服務載入機制進行服務的註冊和發現,可以有效的避免在程式碼中將服務提供者寫死。從而可以基於介面程式設計,實現模組間的解耦。

SPI 機制的約定

  1. 在 META-INF/services/ 目錄中建立以介面全限定名命名的檔案,該檔案內容為API具體實現類的全限定名
  2. 使用 ServiceLoader 類動態載入 META-INF 中的實現類
  3. 如 SPI 的實現類為 Jar 則需要放在主程式 ClassPath 中
  4. 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