看文章之前 首先問自己幾個問題
1.Spring默認(rèn)標(biāo)簽是如何解析注冊的 ?
Spring中標(biāo)簽分為兩種?
? ? ?1.Spring默認(rèn)的標(biāo)簽 如<bean id="account" class
? ? ?2.自定義標(biāo)簽? 如<aop:aspectj-autoproxy
對于不同的標(biāo)簽 有不同的處理方式,如下圖所示:
那我們今天主要來學(xué)習(xí)一下默認(rèn)標(biāo)簽的解析注冊:
Spring的默認(rèn)標(biāo)簽 在DefaultBeanDefinitionDocumentReader#parseDefaultElement中解析注冊bean 如下圖:
默認(rèn)解析標(biāo)簽有import,alias,bean,beans,因為我只寫了個最簡單的domain 所以我們就以標(biāo)簽bean為研究對象展開研究.
進(jìn)入processBeanDefinition方法 :
總結(jié)下來:
1,2 :將元素ele轉(zhuǎn)換封裝成BeanDefinitionHolder?
? ? BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);解析默認(rèn)標(biāo)簽
? ? bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);解析默認(rèn)標(biāo)簽中的自定義標(biāo)簽屬性
?3 :注冊bean
? ??????????1.BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
? ? ? ? ? ? 2.registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition())?
? ? ? ? ? ? 3.DefaultListableBeanFactory#registerBeanDefinition
?4 :通知事件監(jiān)聽器bean注冊成功
如果大家想進(jìn)一步了標(biāo)簽解析封裝過程 可以進(jìn)入1,2方法深入了解一下(后面會詳細(xì)介紹),其實對bean進(jìn)行注冊 自定義標(biāo)簽和默認(rèn)標(biāo)簽都是一樣的 最終都是調(diào)用DefaultListableBeanFactory#registerBeanDefinition中的注冊方法進(jìn)行注冊 ,所謂的注冊bean 就是在DefaultListableBeanFactory 維護的beanDefinitionMap中存bean name 和對應(yīng)的BeanDefinition的關(guān)聯(lián)關(guān)系,注冊后通知時間監(jiān)聽器 我注冊好了!
大概流程了解后我們先進(jìn)入1方法, 了解元素具體解析封裝的過程
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
我們發(fā)現(xiàn)其實這個解析的過程委托給BeanDefinitionParserDelegate#parseBeanDefinitionElement(Element,BeanDefinition)
1解析除了id,beanName外的其他屬性? 并封裝在GenericBeanDefinition中
GenericBeanDefinition是BeanDefinition的子類 ,Spring通過BeanDefinition將配置文件的<bean>配置信息轉(zhuǎn)換為容器的內(nèi)部表示
?2如果沒有beanName 就根據(jù)spring命名規(guī)則為當(dāng)前bean生成對應(yīng)的beanName
進(jìn)入1
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);可以看到對各種屬性的解析,這里就不一個一個分析了 有興趣的小伙伴可以進(jìn)入每個方法好好研究哦!
1.Spring默認(rèn)標(biāo)簽是如何解析注冊的 ?
?答: 默認(rèn)標(biāo)簽的解析注冊 其實是將Element元素解析封裝成BeanDefinitionHolder 然后最終通過DefaultListableBeanFactory#registerBeanDefinition方法進(jìn)行注冊 , 所謂的注冊其實就是在DefaultListableBeanFactory本地維護的beanDefinitionMap中創(chuàng)建beanName和BeanDefinition的映射關(guān)系 當(dāng)然?DefaultListableBeanFactory本地維護的數(shù)據(jù) 遠(yuǎn)不止一個beanDefinitionMap?