dubbo啟動(dòng)過(guò)程淺析

??spring 為第三方預(yù)留了集成的空間欢瞪,當(dāng)spring遇到非自己的命名空間時(shí)活烙,會(huì)去META-INF/spring.handlers文件中尋找此命名空間的處理器,解析xml配置文件時(shí)遣鼓,遇到此命名空間的標(biāo)簽啸盏,調(diào)用對(duì)應(yīng)命名空間標(biāo)簽處理器,解析此標(biāo)簽譬正。那么dubbo怎么做的呢宫补?在dubbo源碼的META-INF目錄下,我們看到有spring.handler文件曾我,打開(kāi)此文件內(nèi)容為:
http://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler
表明dubbo標(biāo)簽的文件處理器為DubboNamespaceHandler粉怕,找到這個(gè)類我們可以發(fā)現(xiàn)所有標(biāo)簽的解析處理邏輯。
??dubbo命名空間下所有的標(biāo)簽都是調(diào)用DubboBeanDefinitionParser進(jìn)行解析抒巢,此方法有兩個(gè)參數(shù)贫贝,一個(gè)是配置類,此配置類會(huì)注冊(cè)到spring IoC容器中蛉谜,另一個(gè)是此bean在IoC容器中是否需要ID標(biāo)識(shí)稚晚。

public BeanDefinitionparse(Element element, ParserContext parserContext) {

        return parse(element, parserContext, beanClass, required);

}

private static BeanDefinitionparse(Element element, ParserContext parserContext, Class beanClass, boolean required) {

    RootBeanDefinition beanDefinition =new RootBeanDefinition();//new一個(gè)beanDefinition

    beanDefinition.setBeanClass(beanClass);

    beanDefinition.setLazyInit(false);//立即初始化

    String id = element.getAttribute("id");

    if ((id ==null || id.length() ==0) && required) {//設(shè)置bean id

        beanDefinition.getPropertyValues().addPropertyValue("id", id);//設(shè)置bean id

    }

    if (ProtocolConfig.class.equals(beanClass)) {//此處是為服務(wù)設(shè)置協(xié)議

    }else if (ServiceBean.class.equals(beanClass)){//若class屬性不為空,ref屬性設(shè)置為class

    }else if (ProviderConfig.class.equals(beanClass)) {//遞歸解析下級(jí)標(biāo)簽

    }else if (ConsumerConfig.class.equals(beanClass)) {

   }

  for (Method setter : beanClass.getMethods()) {

    String name = setter.getName();

    if (name.length() >3 && name.startsWith("set")

      && Modifier.isPublic(setter.getModifiers())

      && setter.getParameterTypes().length ==1) { //取出標(biāo)簽屬性的值型诚,設(shè)置到bean對(duì)象中

      ..........................................................................

    beanDefinition.getPropertyValues().addPropertyValue(property, reference);

    ..........................................................................

  }

    return beanDefinition;

}

DubboBeanDefinitionParser中的parse方法客燕,首先new一個(gè)RootBeanDefinition,然后設(shè)置beanclass值狰贯,將bean的延遲初始化設(shè)為false也搓,接著如下圖所示,如果id為空涵紊,并且id是必須的傍妒,則設(shè)置id值,具體為:
1)先從元素節(jié)點(diǎn)看是否能獲取到name屬性
2)如果獲取不到摸柄,且class為protocolConfig颤练,則將id設(shè)置成dubbo,不是protocolconfig,取接口值
3)如果還是獲取不到驱负,取class的名稱

//將剛才定義的beandefinition注冊(cè)到spring IoC容器中嗦玖,并設(shè)置id值
 if (id != null && id.length() > 0) {
            if (parserContext.getRegistry().containsBeanDefinition(id))  {
                throw new IllegalStateException("Duplicate spring bean id " + id);
            }
            parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);
            beanDefinition.getPropertyValues().addPropertyValue("id", id);
        }

?接下來(lái)對(duì)ProtocolConfig患雇、ServiceBean、ProviderConfig踏揣、ConsumerConfig做特殊處理庆亡。
1)ProtocolConfig:獲取IoC容器里所有的BeanDefinition,然后看這個(gè)bean是否有名稱為protocol的屬性定義捞稿,若有又谋,且協(xié)議為當(dāng)前所解析的協(xié)議,則設(shè)置此bean protocol屬性值為當(dāng)前協(xié)議(此處設(shè)置為動(dòng)態(tài)引用娱局,初始化的時(shí)候才設(shè)置值彰亥,具體可參考spring bean機(jī)制)

2)ServiceBean :如果是<dubbo:service>標(biāo)簽class屬性不為空,將此class設(shè)置成為一個(gè)beandefinition衰齐,并且作為屬性ref的值任斋。(可見(jiàn)ref class兩個(gè)屬性二選1)

3)ProviderConfig、ConsumerConfig:逐層解析下級(jí)標(biāo)簽耻涛,每個(gè)下級(jí)標(biāo)簽解析成一個(gè)beanDefinition废酷,并將provider、consumer作為下級(jí)標(biāo)簽的一個(gè)屬性抹缕,值為動(dòng)態(tài)引用的bean(serviceBean澈蟆、ReferenceBean)

接下來(lái)就是遍歷beanClass中所有的方法(set開(kāi)頭,public修飾卓研,有參數(shù))趴俘,設(shè)置bean中屬性值

for (Method setter : beanClass.getMethods()) {

String name = setter.getName();

    if (name.length() >3 && name.startsWith("set")

&& Modifier.isPublic(setter.getModifiers())

&& setter.getParameterTypes().length ==1) {

      ..............................................................

      beanDefinition.getPropertyValues().addPropertyValue(property, reference);

    ..............................................................

}

?這樣所有配置標(biāo)簽就被解析成beanDefinition交給spring管理,待所有標(biāo)簽都解析完成之后奏赘,spring就會(huì)初始化Bean寥闪,由于serviceBean、ReferenceBean比較特殊磨淌,實(shí)現(xiàn)了一系列接口疲憋,當(dāng)spring在初始化這些這兩個(gè)bean的時(shí)候,會(huì)執(zhí)行相對(duì)應(yīng)的方法梁只,具體如下:

public class ServiceBeanextends ServiceConfig implements InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener, BeanNameAware{

    public void afterPropertiesSet()//完成發(fā)布服務(wù)所需配置的初始化

    public void onApplicationEvent(ApplicationEvent event)//完成服務(wù)的暴露

}

public class ReferenceBeanextends ReferenceConfig implements FactoryBean, ApplicationContextAware, InitializingBean, DisposableBean{

    public void afterPropertiesSet()//完成引用服務(wù)所需配置的初始化

    public ObjectgetObject()throws Exception {
        return get();  //完成服務(wù)的引用
    }
}

總結(jié):由于spring的應(yīng)用廣泛缚柳,包括dubbo在內(nèi)的rpc框架都利用spring IoC容器完成服務(wù)的啟動(dòng)。具體如下:將發(fā)布和引用服務(wù)所需的配置定義成bean--->讀取配置文件敛纲,完成對(duì)bean的填充--->相關(guān)的bean實(shí)現(xiàn)接口--->spring 容器初始化bean的時(shí)候喂击,調(diào)用相應(yīng)的方法完成服務(wù)的發(fā)布和引用剂癌。
一篇好文章:https://nobodyiam.com/2017/02/26/several-ways-to-extend-spring/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末淤翔,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子佩谷,更是在濱河造成了極大的恐慌旁壮,老刑警劉巖监嗜,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異抡谐,居然都是意外死亡裁奇,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門麦撵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)刽肠,“玉大人,你說(shuō)我怎么就攤上這事免胃∫粑澹” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵羔沙,是天一觀的道長(zhǎng)躺涝。 經(jīng)常有香客問(wèn)我,道長(zhǎng)扼雏,這世上最難降的妖魔是什么坚嗜? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮诗充,結(jié)果婚禮上苍蔬,老公的妹妹穿的比我還像新娘。我一直安慰自己其障,他們只是感情好银室,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著励翼,像睡著了一般蜈敢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上汽抚,一...
    開(kāi)封第一講書(shū)人閱讀 49,929評(píng)論 1 290
  • 那天抓狭,我揣著相機(jī)與錄音,去河邊找鬼。 笑死训桶,一個(gè)胖子當(dāng)著我的面吹牛驮履,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播苗桂,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼告组!你這毒婦竟也來(lái)了煤伟?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎便锨,沒(méi)想到半個(gè)月后围辙,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡放案,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年姚建,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吱殉。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡掸冤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出友雳,到底是詐尸還是另有隱情贩虾,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布沥阱,位于F島的核電站缎罢,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏考杉。R本人自食惡果不足惜策精,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望崇棠。 院中可真熱鬧咽袜,春花似錦、人聲如沸枕稀。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)萎坷。三九已至凹联,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間哆档,已是汗流浹背蔽挠。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瓜浸,地道東北人澳淑。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像插佛,于是被迫代替她去往敵國(guó)和親杠巡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350