Dubbo剖析-增強SPI的實現
一、前言
在Duboo剖析-整體架構分析中介紹了dubbo中除了Service 和 Config 層為 API外,其他各層均為SPI,為SPI意味著下面各層都是元件化可以被替換的,這也是dubbo比較好的一點。
二、JDK中標準SPI
JDK 中的 SPI(Service Provider Interface)是面向介面程式設計的,服務規則提供者會在 JRE 的核心 API 裡面提供服務訪問介面,而具體實現則由其他開發商提供。
例如規範制定者在rt.jar包裡面定義了 資料庫 的驅動介面 java.sql.Driver。 MySQL 實現的 Jar,如下:
public class com.mysql.jdbc.Driver extends com.mysql.jdbc.NonRegisteringDriver implements java.sql.Driver
下面我們寫個測試程式碼,看看具體是如何工作的。
public static void main(String[] args) {
//(1)
ServiceLoader<Driver> loader = ServiceLoader.load(Driver.class);
//(2)
Iterator<Driver> iterator = loader.iterator();
while (iterator.hasNext()) {
Driver driver = (Driver) iterator.next();
System.out.println("driver:" + driver.getClass() + ",loader:" + driver.getClass().getClassLoader());
}
//(3)
System.out.println("current thread contextloader:" + Thread.currentThread().getContextClassLoader());
//(4)
System.out.println("ServiceLoader loader:" + ServiceLoader.class.getClassLoader());
}
}
然後引入 MySQL 驅動的 Jar 包,執行結果如下。
driver:class com.mysql.jdbc.Driver,loader:sun.misc.Launcher$AppClassLoader@4554617c
current thread contextloader:sun.misc.Launcher$AppClassLoader@4554617c
ServiceLoader loader:null
可知找到了mysql的驅動,如果你在引入Oracle的驅動的jar包後在執行,則會輸出找到了mysql和Oracle的驅動,這也說明了,JDK標準的SPI會同時把spi介面的所有的實現類都提前載入好。
關於JDK中SPI的原理和具體使用可以參考 Java 類載入器揭祕 中
一種特殊的類載入器 ContextClassLoader 章節。
三、Dubbo增強的SPI
Dubbo 的擴充套件點載入是基於JDK 標準的 SPI 擴充套件點發現機制增強而來的,Dubbo 改進了 JDK 標準的 SPI 的以下問題:
JDK 標準的 SPI 會一次性例項化擴充套件點所有實現,如果有擴充套件實現初始化很耗時,但如果沒用上也載入,會很浪費資源。
如果擴充套件點載入失敗,就失敗了,給使用者沒有任何通知。比如:JDK 標準的ScriptEngine,如果Ruby ScriptEngine 因為所依賴的 jruby.jar 不存在,導致 Ruby ScriptEngine 類載入失敗,這個失敗原因被吃掉了,當使用者執行 ruby 指令碼時,會報空指標異常,而不是報Ruby ScriptEngine不存在。
增加了對擴充套件點 IoC 和 AOP 的支援,一個擴充套件點可以直接 setter 注入其它擴充套件點。
下面看看Dubbo增強的SPI實現的時序圖:
- 其中程式碼(1)獲取當前SPI介面對應的ExtensionLoader
- 程式碼(2)獲取介面卡例項,內部首先獲取該spi對應的所有實現類的Class物件,然後建立介面卡例項,最後注入該介面卡依賴的其他擴充套件點。
- 程式碼(8)根據名稱獲取具體的spi實現類,內部是建立一個實現類的例項,並使用warp類進行包裝後返回。
四、總結
本文簡單的介紹了Dubbo中SPI實現原理,更詳盡的解析 敬請期待
相關文章
- Dubbo2.7的Dubbo SPI實現原理細節
- 詳解Apache Dubbo的SPI實現機制Apache
- Dubbo(一)-SPI(2) 機制之 Dubbo 的 SPI
- Java SPI 與 Dubbo SPIJava
- dubbo之SPI
- 溫習 SPI 機制 (Java SPI 、Spring SPI、Dubbo SPI)JavaSpring
- dubbo的SPI應用與原理
- 基於SPI的增強式外掛框架設計框架
- Dubbo剖析-服務提供方實現類到Invoker的轉換
- Dubbo原始碼解析之SPI原始碼
- dubbo原始碼解析-spi(五)原始碼
- dubbo SPI功能解析(一)
- Dubbo之SPI原始碼分析原始碼
- 剖析 SPI 在 Spring 中的應用Spring
- 深入剖析 Spring Boot 的 SPI 機制Spring Boot
- Java Spi是如何找到你的實現的? ——Java SPI原理與實踐Java
- Dubbo 原始碼分析 - SPI 機制原始碼
- Dubbo和JDK的SPI究竟有何區別?JDK
- 淺析Dubbo的SPI擴充套件機制套件
- 由淺入深理解Dubbo的SPI機制
- Dubbo原始碼解析之SPI機制原始碼
- Dubbo系列之 (一)SPI擴充套件套件
- 搞懂Dubbo SPI可擴充機制
- Dubbo原始碼學習之-SPI介紹原始碼
- Dubbo(一)-SPI 機制之javaSPI基礎Java
- SAP 產品一脈相承的 UI 增強思路,在 SAP電商雲 UI 增強實現中的體現UI
- Dubbo剖析-叢集容錯
- 【一文讀懂】SPI機制之JAVA的SPI實現詳解Java
- 音訊資料增強及python實現音訊Python
- Dubbo原始碼分析(三)Dubbo中的SPI和自適應擴充套件機制原始碼套件
- 從Dubbo核心-SPI聊聊雙親委派機制
- Dubbo SPI 原始碼學習 & admin安裝(二)原始碼
- 聊聊Dubbo(五):核心原始碼-SPI擴充套件原始碼套件
- Java中的增強for迴圈(for each)的實現原理與坑Java
- RunTime實現原理剖析
- SPI機制剖析——基於DriverManager+ServiceLoader的原始碼分析原始碼
- 面試常問的dubbo的spi機制到底是什麼?面試
- 聊聊如何實現一個支援鍵值對的SPI