目錄
- 一個問題
- 什么是SPI
- API 與 SPI
- 一個簡單的例子
- SPI機制的實現
- Java SPI的問題
- 為什么SPI機制打破了雙親委派模型
- 參考資料
MySQL也有可能是Oracle,但是不管使用什么數據庫都是引入數據庫驅動配置相應的地址、用戶、密碼信息就可以使用而不用修改業務代碼 。這是因為在
JDK中提供了一個java.sql.Driver接口 。各個數據庫廠商只需要實現這個接口,當我們引入相應驅動,連接數據庫的時候,就會使用廠商提供的實現,那么又是如何知道廠商實現的類路徑的呢??什么是SPI
SPI全名Service Provider interface,翻譯過來就是“服務提供接口”,再說簡單就是提供某一個服務的接口,提供給服務開發者或者服務生產商來進行實現 。Java SPI 是JDK內置的一種動態加載擴展點的實現 。這個機制在一般的業務代碼中很少用到(個人接觸到的業務沒有用到過),但是再底層框架中卻被大量使用,包括JDBC、Dubbo、Spring框架、日志接口中都有用到,不同的是有的使用Java原生的實現,有的框架則自己實現了一套SPI機制API 與 SPI
API 全稱Application Programming Interface,翻譯為“應用程序接口”,指的是應用程序為外部提供服務的接口,這個接口通常由服務提供者自行開發,定義好接口后很少改動 。API與SPI示意圖如圖1,圖2所示
文章插圖
圖1 API示意圖

文章插圖
圖2 SPI示意圖一般應用(模塊)之間通過接口進行通訊,服務提供方提供接口并進行實現后,調用方就可以通過調用這個接口擁有服務提供發提供的能力,這個就是
API當接口是由服務調用方提供,并且由服務提供方進行實現時,服務調用方就可以根據自己的需要選擇特定實現,而不用更改業務代碼以獲取相應的功能,這個就是SPI一個簡單的例子這個功能是向注冊中心注冊服務的一個示例(過于簡單的示例),
首先定義一個接口
Registry, 這個接口只有一個功能,就是向注冊中心注冊一個服務,但是我現在并不確定我選的是什么注冊中心,于是提供了一個統一的接口,由各個廠商進行實現package cn.bmilk.chat.spi;public interface Registry { void registry(String host, int port);}廠商實現好后,需要在其
META-INF/services文件夾下新增一個文件,文件名為該接口的全限定名即:cn.bmilk.chat.spi.Registry, 內容為接口實現的全限定名,這里我寫了兩個cn.bmilk.chat.spi.EurekaRegistrycn.bmilk.chat.spi.ZookeeperRegistry兩個類的都是空實現,內容如下
@Override public void registry(String host, int port) { System.out.println(this + "registry , host = " + host +" port = " + port); }下面編寫測試主類,通過
ServiceLoader 加載 Registry 實現public class MainTest { public static void main(String[] args) { ServiceLoader<Registry> load = ServiceLoader.load(Registry.class); Iterator<Registry> iterator = load.iterator(); while (iterator.hasNext()){ Registry registry = iterator.next(); registry.registry("127.0.0.1", 10086); } }}
經驗總結擴展閱讀
- 九 Istio:istio安全之授權
- 分布式ID生成方案總結整理
- GCC 指令詳解及動態庫、靜態庫的使用
- 五 Istio:使用服務網格Istio進行流量路由
- pta第二次博客
- java中GC的日志認識詳解
- 2023年摩羯座財運1月運程詳解如何提高
- 即興小探華為開源行業領先大數據虛擬化引擎openLooKeng
- JUC中的AQS底層詳細超詳解
- 圖文詳解 微服務 Zipkin 鏈路追蹤原理
