dubbo中SPI思想

1. dubbo基于SPI思想實現(xiàn)

* SPI:

??我們系統(tǒng)里抽象的各個模塊,往往有很多不同的實現(xiàn)方案,比如日志模塊的方案、xml解析模塊、jdbc模塊的方案等。面向對象的設計里,我們一般推薦模塊之間基于接口編程,模塊之間不對實現(xiàn)類進行硬編碼。一旦代碼里涉及具體的實現(xiàn)類,就違反了可拔插的原則,如果需要替換一種實現(xiàn),就需要修改代碼。
??為了實現(xiàn)在模塊裝配的時候能在程序里動態(tài)指明,這就需要一種服務發(fā)現(xiàn)機制。java spi就是提供這樣的機制:為某個接口尋找服務實現(xiàn)的機制。有點類似IOC的思想,就是將裝配的控制權移到程序之外,在模塊化設計中這個機制尤其重要。

* java中的SPI的約定

??當服務的提供者提供了服務接口的一種實現(xiàn)之后,在jar包的META-INF/services/目錄里同時創(chuàng)建一個以服務接口命名的文件。該文件里面就是實現(xiàn)該服務接口的具體實現(xiàn)類。而當外部程序裝配這個模塊的時候,就能通過該jar包META-INF/services/里面的配置文件找到具體的實現(xiàn)類類名,并裝載實例化,完成模塊的注入?;谶@樣一個約定就能很好的找到服務接口的實現(xiàn)類,而不需要代碼里指定。jdk提供服務實現(xiàn)查找的一個工具類:java.util.ServiceLoader.
??代表例子:jdbc4以前,開發(fā)人員還需要基于Class.forName("XXX")的方式來裝載驅動?,F(xiàn)在jdbc也基于spi機制來發(fā)現(xiàn)驅動提供商了,可以通過META-INF/services/java.sql.Driver文件里面指定實現(xiàn)類的方式來暴露驅動提供者,比如mysql驅動提供者。

- dubbo中基于SPI思想的實現(xiàn)

??dubbo的擴展點加載從JDK標準的SPI擴展點發(fā)現(xiàn)機制加強而來。dubbo改進了JDK標準的SPI的一下問題:

  • JDK標準的SPI會一次性實例化擴展點所有實現(xiàn),如果有擴展實現(xiàn)初始化很耗時,但如果沒用上也加載,會很浪費資源。
  • 如果擴展點加載失敗,連擴展點名稱都拿不到了。比如:JDK標準的ScriptEngine,通過getName();獲取腳本類型的名稱,但如果RubyScriptEngine因為依賴的jruby.jar不存在,導致RubyScript不支持ruby,而不是真正失敗的原因。
  • 增加了對擴展點IoC和AOP的支持,一個擴展點可以直接setter注入其他擴展點。

dubbo擴展點機制的基本概念:

  • 擴展點(Extension Point)一個java接口
  • 擴展(Extension)擴展點實現(xiàn)類
  • 擴展實例(Extension Instance)擴展點實現(xiàn)類的實例
  • 擴展自適應實例(extension Adaptive Instance):擴展點自適應實例其實就是一個Extension的代理,它實現(xiàn)了擴展點接口。在調用擴展點的接口方法時,會根據實際的參數來決定要使用那個擴展點。

SPI接口定義:dubbo定義了注解@SPI用于擴展

public @interface SPI {  
    /**  
     * 缺省擴展點名。  
     */   
    String value() default "";  
}  

當接口打上了該注解時,dubbo會在META-INF/dubbo/internal/接口全名文件下讀取擴展點。
當dubbo啟動時,通過ExtensionLoader類來讀取擴展點中的實現(xiàn)類,首先讀取SPI注解的value值,如果有值作為默認擴展實現(xiàn)的key,然后通過loadFile()一次逐行讀取
META-INF/dubbo/internal/com.alibaba.dubbo.XXX.XXX
META-INF/dubbo/com.alibaba.dubbo.XXX.XXX
文件中的內容

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容