Dubbo——增强SPI的实现
一、前言
在Duboo剖析-整體架構分析中介紹了dubbo中除了Service 和 Config 層為 API外,其他各層均為SPI,為SPI意味著下面各層都是組件化可以被替換的,這也是dubbo比較好的一點。
二、JDK中標準SPI
JDK 中的 SPI(Service Provider Interface)是面向接口編程的,服務規則提供者會在 JRE 的核心 API 里面提供服務訪問接口,而具體實現則由其他開發商提供。
JDBC 4 是基于 SPI 機制來發現驅動提供商提供的實現類,提供者只需在 JDBC 驅動實現的Jar 的 META-INF/services/java.sql.Driver 文件里指定實現類的方式暴露驅動提供者。例如規范制定者在rt.jar包里面定義了 數據庫 的驅動接口 java.sql.Driver。 MySQL 實現的 Jar,如下:
public class com.mysql.jdbc.Driver extends com.mysql.jdbc.NonRegisteringDriver implements java.sql.Driver下面我們寫個測試代碼,看看具體是如何工作的。
然后引入 MySQL 驅動的 Jar 包,執行結果如下。
可知找到了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的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Dubbo相关
- 下一篇: 科普扫盲,HTTP Status Cod