當前位置:編程學習大全網 - 源碼下載 - Dubbo(壹)——Dubbo 集成於 Spring 的原理

Dubbo(壹)——Dubbo 集成於 Spring 的原理

最近壹直在看dubbo的源碼部分。在閱讀的時候,需要有壹個入手點,才能壹點壹點的進行下去。自己在研究的時候,發現思緒比較亂,於是就以 芋道源碼 為基礎,壹點壹點的啃食。芋道源碼是直接從dubbo的配置和壹些核心的API開始講起,是從dubbo已經啟動的過程作為開始節點,而這些核心 API 與 Spring 的之間的關系被省略了,這些東西對我來說屬於前置的知識點,所以花了比較長的時間又從 Dubbo 的核心 API 倒著往前看。

在閱讀 Dubbo 時,發現前置知識越來越多,如:Spring 的 refresh 中的壹些核心點,Spring 中 bean 的生命周期,BeanFactory 與 FactoryBean 的區別等。所以這些前置知識花了特別多的時間去補。所幸,雖然補前置知識雖然時間長,但是性價比還是可以的。Dubbo 是依賴於Spring 的上下文環境的框架,其他依賴於 Spring 的框架也是相同的道理。Spring 的壹些對外的擴展點,讀過之後也會心中有數。

1、本篇主要是描述了 Dubbo 在 Spring 創建上下文的時候,是如何從創建,到能完整提供壹個RPC調用能力的壹些相關點。

2、由於源碼比較多,直接貼斷點也太過臃腫,所以僅僅貼壹些關鍵點來概括整個流程。

3、本文是依賴於前面的 dubbo 項目進行斷點分析,項目結構可以參照這裏。項目中 dubbo 的配置方式是 xml 文件,所以本篇主要說 xml 配置方式。其他方式道理相同,並不是問題的關鍵點。

4、項目啟動的是 dubbo-user 服務,所以 UserService 為 dubbo:service,OrderService 為 dubbo:reference。

下圖為Spring 啟動時是如何加載 Dubbo 的,其中省略了大量過程,只保留了壹些關鍵節點,省略的部分可以略微腦補壹下。

整個流程的入口是 Spring 的 refresh 方法。每個方法都有比較深的調用棧。與 Dubbo 有關的入口是 refresh 中的 invokeBeanFactoryPostProcessors 方法

這個方法是執行 beanFactory 的壹些後處理操作,其核心流程為在Spring容器中找出實現了BeanFactoryPostProcessor接口的processor並執行。Spring容器會委托給PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors方法執行。

ConfigurationClassPostProcessor 是比較核心的類,在這裏我們關註壹下這個類。它的作用是對項目中配置的類進行處理。具體處理可以分為幾步:

在加載類信息時,spring 會去用各種方式掃到註冊的 bean 信息。我們在 spring 中註冊的 bean,逃不出這個方法的掃描方式。 核心方法是:

掃描之後,會將掃描到的 bean 註冊到 beanDefinitionMap 中

首先是此處 org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseBeanDefinitions,可以看出方法會以配置文件根節點起,遍歷所有子節點。

其次是這裏 org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#parseCustomElement(org.w3c.dom.Element, org.springframework.beans.factory.config.BeanDefinition), 此方法會通過解析出來的節點,獲取對應的 Spring 的 namespaceUri ,進而獲取對應的配置文件處理器。

此處 ele 參數實際值為 <dubbo:service ... />,namespaceUri 為 /schema/dubbo

我們看壹下 resolve 方法中的細節。因為這個方法內部才是 Dubbo 依賴於 Spring 的關鍵點。

此處的 NamespaceHandler 為 DubboNamespaceHandler,再創建結束之後,進行 init 初始化。

可以看到,DubboNamespaceHandler 在初始化的時候,會創建所有 dubbo 標簽對應的Config 類的 DubboBeanDefinitionParser。並將 DubboBeanDefinitionParser 和 對應的 dubbo 標簽類註冊到 NamespaceHandlerSupport 的 parsers 中。

最後,會在 com.alibaba.dubbo.config.spring.schema.DubboBeanDefinitionParser#parse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext, java.lang.Class<?>, boolean) 方法中進行處理

Dubbo 服務比較特殊,beanDefinition 跟普通的 bean 不太壹樣。在向 beanDefinitionMap 註冊時,普通的 beanDefinition 的 beanName 與 beanClass 是對應的;而 dubbo 服務的 beanDefinition 的 beanName 是dubbo 服務的名稱,beanClass 為 dubbo 對應的 Bean。

普通的 beanDefinition:

dubbo 引用的服務的 beanDefinition:

這壹步的核心流程是從 beanFactory 中獲取所有的 ApplicationListener,然後註冊到監聽器集合中。它的關鍵點其實是 ServiceBean。因為 ServiceBean 是 ApplicationListener 的實現。

所以 beanFactory 中 ServiceBean 也會被註冊到監聽器集合中。項目中的 ServiceBean 的 beanClass 實際是 UserService。

這壹步的核心點,主要是創建剩余的各類對象,並將其保存到 singletonObjects 中。其中關聯的前置知識為 Spring 中 bean 的生命周期 。它的核心方法是:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

它的具體流程為:

ps:此處並不是只有這壹步才會跟 bean 生命周期相關,bean 生命周期貫穿在 refresh 的很多流程中,只要執行doGetBean 方法,都會走這個流程。此處僅僅借樓關聯壹下。

這壹步的核心點,是通知所有的監聽器上下文刷新結束的事件。在這壹步執行時,會通知到 ServiceBean。

此處暴露的是 UserService。

Dubbo 的啟動條件是完全依賴於 Spring 的啟動流程,Spring 的啟動流程中核心的點是 refresh 方法。所以只要搞懂 refresh 方法,其他的拓展框架流程也會明白。只不過關聯的知識點太多了,還是需要時間的積累才能壹點壹點的搞懂。

如果本篇有描述不清,或者描述有誤的地方,還望在下方留言,大家壹起交流,壹起學習,壹起進步~

  • 上一篇:誰能給我壹些免費的全屏的QQ空間皮膚代碼啊?
  • 下一篇:支付寶源代碼在哪裏
  • copyright 2024編程學習大全網