1. 程式人生 > >Dubbo啟動過程(Spring方式)詳解

Dubbo啟動過程(Spring方式)詳解

一、使用Spring xml配置方式的啟動過程

  1. 解析XML,註冊Bean

  2. 監聽Spring事件

  3. 啟動或關閉dubbo

二、詳細過程

1. 解析XML,註冊Bean

  利用Spring提供的NamespaceHandler擴充套件機制,META-INF下放兩個spring配置檔案,

  spring.schemas定義xsd文件位置,spring.handlers定義XML標籤對應的Handler。

  spring.schemas內容:

 

  spring.handlers內容:

 

  DubboNamespaceHandler繼承NamespaceHandlerSupport(Spring類),並重寫了init()方法。

  在init()方法中,註冊每個標籤對應的解析類(DubboBeanDefinitionParser)。

  

  NamespaceHandlerSupport類中以Map方式儲存標籤名及對應的解析類;

  

  NamespaceHandlerSupport類中的parse(Element element, ParserContext parserContext)方法,是實際的解析入口,

解析時根據標籤名獲取對應的parser,然後再呼叫parser的parse方法(即DubboBeanDefinitionParser中的parse方法)。

  在DubboBeanDefinitionParser的parse方法中,生成BeanDefinition物件,並使用ParserContext中的BeanDefinitionRegistry

註冊到spring容器中,參考BeanDefinitionRegistry#registerBeanDefinition(String beanName, BeanDefinition beanDefinition)。

  注意: dubbo的所有bean都是非懶載入的;

      spring中,需要在parser的parse方法中註冊bean,spring不負責註冊parse方法返回的BeanDefinition。

  另外,關於spring.handlers解析及DubboBeanDefinitionParser的init()方法呼叫,參考spring的DefaultNamespaceHandlerResolver。

2. 註冊監聽Spring事件

  dubbo的jar包中,META-INF目錄下有一個web-fragment.xml檔案(web-fragment工作方式請自行百度)

  

  其關鍵的內容如下,配置了一個context屬性:contextInitializerClasses

  DubboApplicationContextInitializer類原始碼如下:

  

  可以看到,此處將DubboApplicationListener新增到Spring容器中(即AbstractApplicationContext中的listener列表)

  

  DubboApplicationContextInitializer.initialize()方法在Spring中的執行過程:

    web應用中,我們配置web.xml中的Spring啟動監聽器:

    

    ContextLoaderListener中,contextInitialized()方法啟動Spring容器。

    

    ContextLoaderListener繼承了ContextLoader,ContextLoader中customizeContext方法中,

    讀取contextInitializerClasses屬性執行的class(多個class支援 ,; \t\n 四種分隔符),並呼叫其initialize()方法。

  接下來看一下DubboApplicationListener內容:

  

  Spring啟動完成時,產生ContextRefreshEvent事件,並回調所有listener.

  具體程式碼在:AbstractApplicationContext.finishRefresh()方法中:

  

   publishEvent()中,再使用SimpleApplicationEventMulticaster.multicastEvent()方法回撥所有監聽器

  的onApplicationEvent()方法。

  

  

  至此,上述即為dubbo註冊即監聽Spring的過程。

  另外,如果不是web應用是怎麼做的呢?

    Dubbo提供了SpringContainer來啟動非web應用,依然是採用Spring註冊監聽機制

     

3. 啟動dubbo

  由DubboBootstrap.start()方法負責。

  

  詳細的啟動過程下次給出。

 

本人水平有限,文中有不當之處歡迎評論中指出。