dubbo源码解析(一)
大家好,我是烤鴨:
? ? ?今天和大家分享dubbo的源碼解析。
1.SPI
http://dubbo.apache.org/zh-cn/docs/source_code_guide/dubbo-spi.html
介紹:
SPI 全稱為 Service Provider Interface,是一種服務(wù)發(fā)現(xiàn)機(jī)制。
SPI 的本質(zhì)是將接口實(shí)現(xiàn)類的全限定名配置在文件中,并由服務(wù)加載器讀取配置文件,加載實(shí)現(xiàn)類。這樣可以在運(yùn)行時(shí),動(dòng)態(tài)為接口替換實(shí)現(xiàn)類。
Dubbo重寫(xiě)了Java原生的SPI。Dubbo SPI 是通過(guò)鍵值對(duì)的方式進(jìn)行配置,按需加載指定的實(shí)現(xiàn)類。
源碼:
com.alibaba.dubbo.common.extension.ExtensionLoader?
getExtension:
獲取拓展類對(duì)象。
createExtension:
1. 通過(guò) getExtensionClasses 獲取所有的拓展類
2. 通過(guò)反射創(chuàng)建拓展對(duì)象
3. 向拓展對(duì)象中注入依賴 (injectExtension)
4. 將拓展對(duì)象包裹在相應(yīng)的 Wrapper 對(duì)象中
將產(chǎn)生的wrapper對(duì)象放到 objectFactory 。
objectFactory 變量的類型為 AdaptiveExtensionFactory,AdaptiveExtensionFactory 內(nèi)部維護(hù)了一個(gè) ExtensionFactory 列表,用于存儲(chǔ)其他類型的 ExtensionFactory。Dubbo 目前提供了兩種 ExtensionFactory,分別是 SpiExtensionFactory 和 SpringExtensionFactory。前者用于創(chuàng)建自適應(yīng)的拓展,后者是用于從 Spring 的 IOC 容器中獲取所需的拓展。?
Dubbo IOC 目前僅支持 setter 方式注入。
2.動(dòng)態(tài)加載
http://dubbo.apache.org/zh-cn/docs/source_code_guide/adaptive-extension.html
介紹:
拓展方法被調(diào)用時(shí),根據(jù)運(yùn)行時(shí)參數(shù)進(jìn)行加載。 Dubbo 會(huì)為拓展接口生成具有代理功能的代碼。然后通過(guò) javassist 或 jdk 編譯這段代碼,得到 Class 類。最后再通過(guò)反射創(chuàng)建代理類,整個(gè)過(guò)程比較復(fù)雜。
源碼:
@Adaptive?
當(dāng) Adaptive 注解在類上時(shí),Dubbo 不會(huì)為該類生成代理類。注解在方法(接口方法)上時(shí),Dubbo 則會(huì)為該方法生成代理邏輯。
com.alibaba.dubbo.common.extension.ExtensionLoader?
getAdaptiveExtension:
創(chuàng)建自適應(yīng)拓展。
createAdaptiveExtension:
1. 調(diào)用 getAdaptiveExtensionClass 方法獲取自適應(yīng)拓展 Class 對(duì)象
2. 通過(guò)反射進(jìn)行實(shí)例化
3. 調(diào)用 injectExtension 方法向拓展實(shí)例中注入依賴
getAdaptiveExtensionClass:
1. 調(diào)用 getExtensionClasses 獲取所有的拓展類
2. 檢查緩存,若緩存不為空,則返回緩存
3. 若緩存為空,則調(diào)用 createAdaptiveExtensionClass 創(chuàng)建自適應(yīng)拓展類動(dòng)態(tài)生成代碼(類):
代碼生成的順序與 Java 文件內(nèi)容順序一致,首先會(huì)生成 package 語(yǔ)句,然后生成 import 語(yǔ)句,緊接著生成類名等代碼。
動(dòng)態(tài)生成代碼(方法):
Dubbo 不會(huì)為沒(méi)有標(biāo)注 Adaptive 注解的方法生成代理邏輯,對(duì)于該種類型的方法,僅會(huì)生成一句拋出異常的代碼。
?獲取 URL 數(shù)據(jù):
?要為 Protocol 接口的 refer 和 export 方法生成代理邏輯。
?通過(guò)遍歷 refer 的參數(shù)列表即可獲取 URL 數(shù)據(jù),export 參數(shù)列表中沒(méi)有 URL 參數(shù),因此需要從 Invoker 參數(shù)中獲取 URL 數(shù)據(jù)。獲取方式是調(diào)用 Invoker 中可返回 URL 的 getter 方法,如果 Invoker 中無(wú)相關(guān) getter 方法,此時(shí)則會(huì)拋出異常。
?生成后如下:
獲取 Adaptive 注解值:
Adaptive 注解值 value 類型為 String[],可填寫(xiě)多個(gè)值,默認(rèn)情況下為空數(shù)組。若 value 為非空數(shù)組,直接獲取數(shù)組內(nèi)容即可。若 value 為空數(shù)組,則需進(jìn)行額外處理。比如 LoadBalance 經(jīng)過(guò)處理后,得到 load.balance。
檢測(cè) Invocation 參數(shù):
檢測(cè)方法列表中是否存在 Invocation 類型的參數(shù),若存在,則為其生成判空代碼和其他一些代碼。
生成拓展名獲取邏輯:
本段邏輯用于根據(jù) SPI 和 Adaptive 注解值生成“獲取拓展名邏輯”,同時(shí)生成邏輯也受 Invocation 類型參數(shù)影響,綜合因素導(dǎo)致本段邏輯相對(duì)復(fù)雜。本段邏輯可以會(huì)生成但不限于下面的代碼:
生成拓展加載與目標(biāo)方法調(diào)用邏輯:
本段代碼邏輯用于根據(jù)拓展名加載拓展實(shí)例,并調(diào)用拓展實(shí)例的目標(biāo)方法。
以 Protocol 接口舉例說(shuō)明,上面代碼生成的內(nèi)容如下:
生成完整的方法:
以 Protocol 的 refer 方法為例,上面代碼生成的內(nèi)容如下:
?
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的dubbo源码解析(一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Android develop 国际化
- 下一篇: 大一c语言期末考试编程题