?我們知道,在dubbo與spring的整合后,我們可以輕易的通過@Autowired引入bean并使用囱皿,那么問題來了,dubbo與spring內(nèi)部到底是怎么整合的呢忱嘹?
一嘱腥、拋出問題
1、dubbo的xml配置文件拘悦,bean對象時(shí)怎么導(dǎo)入到beanFactory中的齿兔?
2、我們知道,spring中bean的定義需要指定id分苇,dubbo中既然沒有id的屬性 添诉,也沒有Bean標(biāo)簽,那么注入到beanFactory中的beanId到底是什么医寿?
二栏赴、閱讀前需學(xué)的知識(shí)點(diǎn)
spring IOC中比較核心的知識(shí)點(diǎn)
BeanDefinition、InitializingBean ApplicationContextAware靖秩、ApplicationListener<ContextRefreshedEvent>, BeanNameAware
三须眷、開始學(xué)習(xí)
1、schema擴(kuò)展機(jī)制
程序設(shè)計(jì)原則中有一條非常重要的原則沟突,即開閉原則花颗,主要方便開發(fā)者做相應(yīng)的擴(kuò)展,spring在schema的設(shè)計(jì)上亦是如此惠拭。 spring提供了對schema的擴(kuò)展扩劝,開發(fā)者可以自己定義schema文件,并定義其相應(yīng)的解析器以及與spring ioc的集成求橄。
實(shí)現(xiàn)schema擴(kuò)展一般的步驟為:
1)定義xsd文件今野。 可以參考dubbo源碼中META-INF->dubbo.xsd,該文件定義了dubbo中所有的標(biāo)簽規(guī)范罐农,如:? dubbo:service条霜、dubbo:reference等等。
2)定義NamespaceHandler涵亏≡姿可以參考dubbo源碼中的DubboNamespaceHandler
3)定義BeanDefinitionParse,即Bean的解析器气筋。
4) 配置NameSpace對應(yīng)的xsd文件拆内。見META-INF->spring.shcemas文件。 本人對spring.shcemas文件沒有詳細(xì)的深究宠默,但是很容易發(fā)現(xiàn)麸恍,該文件再很多框架中都被用到了,比如:druid搀矫、apollo等等抹沪,spring框架中應(yīng)該會(huì)自動(dòng)加載該文件
5)配置NameSpace對應(yīng)的Handler類。見META-INF->spring.handlers瓤球。
spring源碼在這就不做相應(yīng)的分析融欧,在項(xiàng)目啟動(dòng)時(shí),spring會(huì)調(diào)用DubboNamespaceHandler中的init方法卦羡,注冊dubbo標(biāo)簽對應(yīng)的BeanDefinitionParser解析器以及其對應(yīng)的實(shí)現(xiàn)噪馏,比如:dubbo:application標(biāo)簽對應(yīng)的ApplicationConfig類麦到、dubbo:service標(biāo)簽對應(yīng)的ServiceBean類。
2欠肾、Bean的創(chuàng)建過程
? ? ? ?在上一節(jié)中瓶颠,我們定義不同標(biāo)簽對應(yīng)的不同實(shí)現(xiàn),本節(jié)我們將分析Bean的創(chuàng)建已經(jīng)我們最終的BeanName到底是什么董济。
? ? ? ?spring底層的源碼在這里不做詳細(xì)介紹步清,其實(shí)spring在解析Bean的時(shí)候會(huì)根據(jù)我們注冊到spring中不同標(biāo)簽對應(yīng)到不同BeanDefinitionParser做解析,比如dubbo的標(biāo)簽虏肾,對應(yīng)的解析器都是DubboBeanDefinitionParser類廓啊,spring中會(huì)調(diào)用類中的parse方法。我們拋開細(xì)節(jié)看一些關(guān)鍵的點(diǎn):
1)BeanDefinition封豪,dubbo底層其實(shí)還是基于spring的BeanDefinition來生成bean的谴轮。
2)BeanName名稱怎么定義的? 首先從標(biāo)簽中獲取id吹埠,id取不到第步,id取不到獲取name屬性,name屬性也為空的情況下缘琅,會(huì)獲取interface屬性粘都。賦值到id中
按照id類生成BeanDefinition。
那么現(xiàn)在看應(yīng)該就比較清晰了刷袍,dubbo:refrence對應(yīng)的beanId即為對應(yīng)的id屬性翩隧,而dubbo:service對應(yīng)的beanId就是它的interface屬性值。
3呻纹、ServiceBean源碼
serviceBean類其實(shí)是服務(wù)發(fā)布的核心類堆生,只看大概,核心怎么向注冊中心注冊服務(wù)的雷酪,后期再詳細(xì)介紹淑仆。
上一節(jié)我們介紹的,每個(gè)dubbo:service對應(yīng)的其實(shí)是一個(gè)創(chuàng)建ServiceBean的過程哥力,serviceBean實(shí)現(xiàn)了幾個(gè)重要的接口InitialzingBean蔗怠、BeanNameAware、ApplicationContextAware吩跋、ApplicationListener<ContextRefreshEvent>接口蟀淮。
其中afterPropertiesSet()方法、onApplicationEvent(ContextRefreshedEvent event)方法的實(shí)現(xiàn)都有想注冊中心注冊服務(wù)的邏輯钞澳,afterPropertiesSet是spring bean生命周期的一個(gè)過程(即為創(chuàng)建bean時(shí)候注冊),onApplicationEvent(ContextRefreshedEvent event)監(jiān)聽的ApplicationContext刷新(即在ApplicationContext刷新之后注冊)涨缚。? ? ?內(nèi)部是通過是否延遲加載來控制的轧粟,如果非延遲則在bean創(chuàng)建時(shí)注冊策治,如果延遲則在刷新spring上下文時(shí)注冊。? ? ?注冊的源碼在此章不做詳解兰吟。
因網(wǎng)上找了些文章通惫,有些細(xì)節(jié)的點(diǎn)沒有講到,比如beanId怎么定義的混蔼,所以擼了源碼后自己寫了一篇履腋。本人第一次寫,有寫的不好的地方還請指出惭嚣。