深入Dubbo源碼 – Dubbo配置文件解析

  • 2019 年 10 月 5 日
  • 筆記

本文代碼:https://github.com/GloryXu/test-project.git

從16年開始接觸Dubbo,剛開始覺得很神奇,配置非常簡潔,與Spring配置無縫銜接。上網各種搜索,Zookeeper + Provider + Consumer,測試項目跑起來了,很開心。但是對於源碼總是狠不下心學習,那麼多類,那麼多英文注釋,嚇退我了。最近終於狠下心來一點一點的Debug代碼,終於有了點收貨,記錄下。

Dubbo配置文件Demo

Provider配置文件

<?xml version="1.0" encoding="UTF-8"?>  <beans xmlns="http://www.springframework.org/schema/beans"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"         xsi:schemaLocation="http://www.springframework.org/schema/beans             http://www.springframework.org/schema/beans/spring-beans-3.2.xsd             http://code.alibabatech.com/schema/dubbo             http://code.alibabatech.com/schema/dubbo/dubbo.xsd">        <dubbo:application name="test-dubbo" />        <dubbo:registry protocol="zookeeper" address="${dubbo.registry.address}"/>        <dubbo:protocol name="dubbo" port="${dubbo.registry.port}"/>        <dubbo:service interface="com.redsun.dubbo.provider.ProviderI" ref="providerImpl"/>    </beans>

Properties文件中的配置

dubbo.registry.address=zookeeper://127.0.0.1:2181

Consumer配置文件

<?xml version="1.0" encoding="UTF-8"?>  <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"         xsi:schemaLocation="http://www.springframework.org/schema/beans             http://www.springframework.org/schema/beans/spring-beans-3.2.xsd             http://code.alibabatech.com/schema/dubbo             http://code.alibabatech.com/schema/dubbo/dubbo.xsd">        <dubbo:application name="test-dubbo-consumer"  />        <!-- 使用zookeeper集群註冊中心暴露發現服務地址 -->      <dubbo:registry address="${dubbo.registry.address}" timeout="2500" />        <!--<dubbo:protocol host="192.168.30.56" />-->        <dubbo:reference id="providerI" interface="com.redsun.dubbo.provider.ProviderI"/>  </beans>

Properties配置同Provider

Dubbo配置文件加載

Spring的加載過程非常繁瑣,哪裡強大?待我日後慢慢道來,其實看懂了本篇文章,對於Spring加載也能有點了解,今天主要說Dubbo的配置文件加載和解析。

Spring識別Dubbo配置文件

在Spring的加載配置文件的時候,首先要做的就是解析配置文件,在解析發現節點是 import的時候,會再進行讀取和解析 resource中的配置文件信息。詳見如下,定心的詳細的Debug跟蹤Spring加載代碼,不難發現,此處貼上關鍵代碼

讀取Dubbo配置文件之後

讀取文件之後就會開始解析 dubbo-provider.xml文件,詳見下圖

繼續跟

在解析完元素之後,怎麼就將解析權限交給 Dubbo.jar了呢,之前我們所跟蹤的代碼都是Spring代碼中的,此處給出了答案。通過識別元素是Dubbo開頭的來獲取 dubbo-provider.xml配置文件中的頭信息,就是我們常說的Schema,來獲取Dubbo中的解析Handler –> DubboNamespaceHandler

Spring會獲取 META-INF/spring.handlers中的信息,大家也許會對這個文件很陌生,我們來看看這裏面的信息

http://dubbo.apache.org/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler  http://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler

有沒有豁然開朗的感覺,在此配置文件中配置了 http://code.alibabatech.com/schema/dubbo此schema所對應的Handler了,有興趣的同學可追蹤下獲取Handler的代碼。

:其實Spring也有相應的 META-INF/spring.handlers文件,裏面也有類似的配置信息,有興趣的同學可以自行跟蹤下

Dubbo配置文件解析

好了,在獲取到Dubbo的Handler之後又做了什麼呢?

DubboNamespaceHandler — Dubbo處理器

這裡相信大家就不陌生了吧,此處將Dubbo配置文件中的所有相關的節點都定義了對應的BeanDefinition解析器,此時也就不難想到,在解析到對應的節點時就去獲取對應的parsers。

Service的解析

此處我們姑且跟蹤下Service節點的parse詳情。

按照我們之前所想,開始解析了,並讀取service節點信息進行作相應的操作了。 什麼操作呢?

DubboNamespaceHandlerinit方法中我們就知道service所對應的 beanClass就是 ServiceBean,此處的目的是通過反射來獲取beanClass的所有是public的單個參數的set方法,並查看是否在配置文件中有了對應的配置,如果有則設置到 beanDefinition對象中。那麼這個對象最終存在了哪裡?在這裡!

這一行代碼太隱蔽了,不仔細很難發現。熟悉Spring源碼的應該知道有一個BeanMap用於存放所有的Bean信息。

到此,配置文件中的service配置終於轉化成一個內存中的對象了,也完成了解析的過程。

總結

之前總是狠不下心看源碼,難,多,每次都退卻了。靜下心來跟一下,在熟悉代碼的過程中還能學習更多的細節。比如在配置文件中使用classpath配置路徑時,如果「:」無意寫了個"/"並沒有什麼影響,Spring代碼會subString的。

閱讀源碼,在路上,後續還會有~~