1.2.14.1 什麼是 SPI
SPI 全稱 Service Provider Interface,是 Java 提供的一套用來被第三方實作或者擴充的接口,它可以用來啟用架構擴充和替換元件。 SPI 的作用就是為這些被擴充的 API 尋找服務實作。
1.2.14.2 SPI 和 API 的使用場景
- API (Application Programming Interface)在大多數情況下,都是實作方制定接口并完成對接口的實作,調用方僅僅依賴接口調用,且無權選擇不同實作。 從使用人員上來說,API 直接被應用開發人員使用。
- SPI (Service Provider Interface)是調用方來制定接口規範,提供給外部來實作,調用方在調用時則選擇自己需要的外部實作。 從使用人員上來說,SPI 被架構擴充人員使用。
1.2.14.3 簡單實作
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI2EzX4xSZz91ZsAzNfRHLGZkRGZkRfJ3bs92YsAjMfVmepNHL9MXVMllRFVVQClGVF5UMR9Fd4VGdsATNfd3bkFGazxycykFaKdkYzZUbapXNXlleSdVY2pESa9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL4UzMwYGM4cDZzEWZwIzNiZmMwQTNzIWYmhjN2YTMxIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
調用方
建立一個調用方項目,負責 SPI 調用。
- 定義接口
public interface IShout {
/**
* 發出叫聲
*/
void shout();
}
- 注冊接口實作類
在 resources 目錄下建立 META-INF/services 目錄,并且在這個目錄下建立一個與上述接口的全限定名一緻的檔案,在這個檔案中寫入接口的實作類的全限定名。
// 文本檔案 resources/META-INF/services/cn.dt.IShout
cn.dt.Cat
cn.dt.Dog
- 通過 serviceLoader 加載實作類并調用
ServiceLoader<IShout> shouts = ServiceLoader.load(IShout.class);
for (IShout shout : shouts) {
shout.shout();
}
實作方
建另一個項目,提供調用項目中接口的實作。
- 定義實作類
public class Cat implements IShout {
@Override
public void shout() {
System.out.println("喵喵喵...");
}
}
public class Dog implements IShout {
@Override
public void shout() {
System.out.println("汪汪汪...");
}
}
-
打包 jar
将項目打包成 jar, 作為第三方庫提供給調用方使用。
調用
- 将實作方 jar 放到調用方項目 lib 目錄下,并加入運作依賴
- 執行調用程式