SPI(service provider interface 服務提供者介面)
阿新 • • 發佈:2019-01-30
零. 簡介
SPI 是 JDK 1.5 後提供的一種服務擴充套件介面。目前有不少框架用它來做服務的擴充套件,如 Dubbo。
服務通常指介面(下述例子的 Hello 介面)或者抽象類,服務提供方(下述例子的CHello、JavaHello 類)就是對這個介面或者抽象類的實現,然後按spi標準存放到資源路徑META-INF/services目錄下,檔案的命名(下述例子的 com.wenniuwuren.spi.Hello)為該介面的全限定名,檔案內容每一行寫一個服務實現類,#
號後面為註釋,該檔案只能是 UTF-8 編碼。再按 SPI 規範打包成 jar,再放到 classpath,沒有一點程式碼的侵入性 。
本質上和我們通常的開發方式一樣,定義介面,子類實現父類,那很多人有疑問,為什麼要開發這麼一套規範? 這種方式主要是針對不同的服務提供方(外掛開發、功能擴充套件等),對不同場景的提供不同的解決方案制定的一套標準,舉個例子,如現在的 JDK 中支援資料庫連線池,如果只支援某個連線池如 Druid,如果其他公司不想用這個 Druid 連線池,如果沒有提供 SPI 擴充套件,那就只有修改
Java 的原始碼,那就有個問題,要升級 JDK 就得再改一次程式碼,而有了 SPI 標準,JDK 只需要提供一個連線池介面,在實現連線池的功能上通過 ServiceLoad 的方式載入服務,那麼第三方只需要實現這個連線池介面,就可以提供不同的服務。
一. 程式碼示例
SPI 服務提供方:
pom.xml 打包示例配置:
Maven 專案結構:
SPI 服務介面:
package com.wenniuwuren.spi;
/**
* Created by hzzhuyibin on 2017/2/14.
*/
public interface Hello {
void sayHello();
}
SPI 服務提供方:
package com.wenniuwuren.spi.impl; import com.wenniuwuren.spi.Hello; /** * Created by hzzhuyibin on 2017/2/14. */ public class JavaHello implements Hello{ @Override public void sayHello() { System.out.println("Java Hello"); } } package com.wenniuwuren.spi.impl; import com.wenniuwuren.spi.Hello; /** * Created by hzzhuyibin on 2017/2/14. */ public class CHello implements Hello{ @Override public void sayHello() { System.out.println("C Hello"); } }
配置檔案 META-INF/services/com.wenniuwuren.spi.Hello:
com.wenniuwuren.spi.impl.CHello # C Hello
com.wenniuwuren.spi.impl.JavaHello # Java Hello
pom.xml 打包示例配置: