1. 程式人生 > >Dubbo定義的元素註冊到Spring容器的原理解析

Dubbo定義的元素註冊到Spring容器的原理解析

Spring對第三方自定義元素配置的支援
  1. Spring中bean的定義可以通過程式設計,可以定義在properties檔案,也可以定義在通過xml檔案中,用的最多的是通過xml形式,由於xml格式具有很好的自說明便於編寫及維護。對於xml的文件結構、資料定義及格式驗證可以通過DTD和Schema, 在spring2.0之前採用的是DTD,在spring2.0之後採用Schema。使用Schema方式使得spring更加便於與第三方進行整合以及第三方可以提供更簡單更便於使用的個性化配置方式。
    對於XmlSchema,有個重要的概念名稱空間(namespace)必須要提一下,spring就是利用它來做第三方自定配置格式的解析的,在spring中aop, transaction的就是一個實現自己自定義配置很好例項。
    這裡寫圖片描述

    如上圖:xmlns=http://www.springframework.org/schema/beans是預設名稱空間
    xmlns:aop=http://www.springframework.org/schema/aop 定義的aop的名稱空間
    xmlns:tx=”http://www.springframework.org/schema/tx” 定義了事物的名稱空間
  2. spring通過schema方式來解析配置檔案的基本原理:
    類DefaultBeanDefinitionDocumentReader會把spring的xml配置檔案當做一個文件格式來讀取。
    這裡寫圖片描述
    每讀取一個元素節點都會判斷下這個元素的名稱空間,如果是預設名稱空間(
    http://www.springframework.org/schema/beans
    )則按預設方式讀取bean的定義。如果不是如namespaceUri如下:
    http://www.springframework.org/schema/aop,
    http://www.springframework.org/schema/tx,
    http://code.alibabatech.com/schema/dubbo
    則走解析自定義元素流程。根據名稱空間去獲取具體的處理器NamespaceHandler
    這裡寫圖片描述
    DefaultNamespaceHandlerResolver類傳了key為namespaceUri,在類中有個Map儲存類所有的自定義NamespaceHandler,這個Map中的值是通過工具類PropertiesLoaderUtils載入所有在”META-INF/spring.handlers”中的值
    這裡寫圖片描述

    這裡寫圖片描述
解析Dubbo自定義的元素到註冊Spring容器中

這裡寫圖片描述
DubboNamespaceHandler中註冊了這麼多的BeanDefinitionParser用來解析dubbo定義的那些xml元素節點如:

<dubbo:application name="dubbo-admin" />
<dubbo:registry address="${dubbo.registry.address}" check="false"file="false" />
<dubbo:reference id="registryService"interface="com.alibaba.dubbo.registry.RegistryService"check="false" />
<dubbo:reference id="demoService"interface="com.alibaba.dubbo.demo.DemoService" />
<dubbo:service interface="com.alibaba.dubbo.demo.DemoService"ref="demoService" />

各個BeanDefinitionParser會把上面的xml元素轉換成spring內部的資料結構BeanDefinition,最終當被引用時例項化成對應的bean如<dubbo:application/>節點得到ApplicationConfig。當然通過預設配置方式也是可以的如:

<dubbo:registry address="${dubbo.registry.address}" check="false"file="false" />

也可以配置成

<bean id="registry" class="com.alibaba.dubbo.config.RegistryConfig"/>
    <property name="address" value="${dubbo.registry.address}"/>
    <property name="check" value="false"/>
    <property name="file" value="false"/>
<bean/>

利用自定義元素解析更加簡潔,同時也可以遮蔽一些具體的實現型別,如你不需要知道com.alibaba.dubbo.config.RegistryConfig這個類,只需要知道註冊registry這個元素就可以了,使用者可以通過文件以及schema的在ide中的自動提示可以很方便的去配置。