Dubbo–服務擴展及初始化
寫在前面
本文參考了Dubbo官方手冊結合Dubbo2.6.1版本源碼分析。推薦先閱讀官方手冊。
鑑於個人水平有限,如有不正確的地方請指出,歡迎一起討論,謝謝!
服務擴展
Dubbo使用類似於SPI的方式進行服務擴展管理,從大量服務提供接口中選擇實際提供服務的接口,並根據配置對服務添加配置包裝類(第5步)。大致流程如下:
- 向ExtensionLoader類的getExtensionLoader方法傳入的class類型對象,此對象必須是接口類型,必須有SPI註解。
- ExtensionLoader根據類型優先從緩存(包括緩存的活動服務、緩存的所有服務類)中獲取class對象的服務提供類,獲取到後直接返回緩存的服務提供類。
- 如果無緩存則加載META-INF/dubbo/internal/、META-INF/dubbo/、META-INF/services/三個目錄下以class對象名爲名的文件,從文件中獲取所有服務提供類(服務提供類必須是getExtensionLoader方法傳入的class類型對象的實現類)。從此步驟開始,都是線程安全的。
- 從所有的服務類中獲取有Adaptive註解的類作爲實際服務提供類(多個同類型的服務提供類只能有一個類有Adaptive註解,否則會報錯)。
- 將服務類中包含有接口參數構造方法(如ProtocolListenerWrapper(Protocol protocol))的服務類作爲Wrapper類處理,Wrapper類會在後續根據名稱獲取實際服務類時(獲取默認類getAdaptiveExtension時不會包裝)包裝實際服務類,即返回的始終是Wrapper類。如果有多個Wrapper類,則使用最後加載Wapper類作爲最外層包裝(裝飾器模式)。
- 對於帶有類註解Activate的服務類緩存到cachedActivates中,供後續的getActivateExtension方法使用。
- 如果配置文件中未包含有Adaptive註解的服務提供類,則動態創建一個類名爲class類$Adaptive實現class接口的服務提供類作爲實際服務提供類,並編譯此類。
- 此處要求class對象對應的接口中必須包含有帶Adaptive註解的方法。
- 動態創建的類只會實現帶Adaptive註解的方法。
- 動態創建類的方法會根據Adaptive註解優先使用URL中的同名參數值,默認使用class接口SPI註解中的value值從ExtensionLoader中查找對應的服務實現類。
- 當Adaptive註解有多個URL參數時,右側優先嵌套獲取。
- 無論是動態創建的類還是擴展服務類在構建時會根據set方法注入其他擴展服務實現(ExtensionLoader.injectExtension實現)。
綜上,Dobbo本身的服務擴展會默認使用自身註解代表的服務提供類,對於非動態生成類則優先使用Adaptive註解修飾的類,對於動態生成類則一般優先使用Adaptive註解中參數名對應的URL參數值指代的類。
初始化過程
Dubbo初始化的過程就是通過自身擴展的命名空間以及相應BeanDefinitionParser接口的實現類,在Spring初始化時將配置中的標籤轉化爲固定類型的BeanDefinition。同時,在BeanDefinition生成Spring Bean時,通過服務擴展將聲明在各個jar包中的默認服務類組裝到實際使用類中建議參閱Spring擴展及初始化分析。大致過程如下:
- 根據標籤,設置BeanDefinition具體的bean類型
- 設置BeanDefinition的默認屬性:非懶加載
- 根據標籤屬性(id、name、interface等)設置BeanDefinition的PropertyValues中id屬性名的屬性值
- 如果是協議配置類,則將所有屬性名爲protocol的屬性值設置爲引用類型,且引用爲BeanDefinition
- 如果是服務提供類且是通過class屬性聲明服務,則將class屬性指向的類註冊爲BeanDefinition,同時將服務提供類的ref屬性設置爲class屬性實例
- 如果是提供者或者消費者配置,則嵌套解析其內部的聲明
- 獲取同時存在於bean中getter/setter方法的後綴,認爲其爲類屬性名,通過解析聲明向BeanDefinition的PropertyValues中添加屬性名以及其屬性值
- BeanDefinition在實例化時,根據內部對ExtensionLoader的調用,將實際服務提供類注入到各個類中。或者根據屬性名將其他的配置Bean注入到當前Bean。
一級標籤說明
標籤 | 實現類 | 解釋 |
---|---|---|
<dubbo:application/> |
ApplicationConfig | 定義應用信息,包括應用名稱等信息。可以重複。 |
<dubbo:module/> |
ModuleConfig | 用於配置當前模塊信息,可選。與Application無從屬關係。可能通過organization與Application關聯。 |
<dubbo:registry/> |
RegistryConfig | 用於配置連接註冊中心相關信息,包括地址、協議名、認證信息等。 |
<dubbo:monitor/> |
MonitorConfig | 用於配置連接監控中心相關信息,可選。 |
<dubbo:provider/> |
ProviderConfig | 服務提供者的默認配置信息,優先級低於具體配置類的自身配置值。可選。 |
<dubbo:consumer/> |
ConsumerConfig | 服務消費者的默認配置信息,優先級低於具體配置類的自身配置值。可選。 |
<dubbo:protocol/> |
ProtocolConfig | 用於配置提供服務的協議信息,協議由提供方指定,消費方被動接受 |
<dubbo:service/> |
ServiceBean | 用於暴露一個服務,定義服務的元信息,一個服務可以用多個協議暴露,一個服務也可以註冊到多個註冊中心。每一個URL代表一個唯一的ServiceBean。 |
<dubbo:reference/> |
ReferenceBean | 用於創建一個遠程服務代理,一個引用可以指向多個註冊中心 |
<dubbo:annotation/> |
方法配置 | 用於處理類中的註解 |