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()方法負責。
詳細的啟動過程下次給出。
本人水平有限,文中有不當之處歡迎評論中指出。