Spring自定義標籤使用及原理

   最近大半年一直在看spring的源碼,尋思着需要寫點什麼,也鍛鍊下自己文檔編寫的能力。本篇我們講解spring自定義標籤的使用及原理,分爲以下小節進行講解。

  1. 自定義標籤的用途
  2. 自定義標籤使用
  3. 自定義標籤如何被spring解析

    1.自定義標籤的用途


    自定義標籤可以說是spring提供的最大、最強的Hook(鉤子),通俗的講就是給後續小夥伴開發組件,提供一個標準公共可拔插”接口”,大家可以理解爲手機充電器的工業標準口,爲了方便各個充電器生產廠家生產,而制定的標準。
    既然說自定義標籤如此強大,我們在哪裏應用的呢? 我們知道spring發展越來越強大,但核心的組件只有spring-core和spring-beans,那麼有些人會問我們經常用的context,aop,tx不是嗎?對的,這些都是在覈心上做的擴展,而這些擴展恰恰是通過自定義標籤實現擴展的,還有一些公共開源組件amq,redis,dubbo等等,他們都利用了自定義標籤來擴展,使得spring容器的功能越發強大。

2.自定義標籤使用


    既然自定義標籤用途那麼廣,那麼如何使用自定義標籤呢?這裏我將帶領大家感受下自定義標籤的使用。需要的文件(按照spring加載、解析的順序)有以下五個基本文件:
①spring.schemas
②XSD文件
③spring.handlers
NamespaceHandler
BeanDefinitionParser
⑥最後引入到配置文件中使用。
基本自定義標籤需要實現兩個關鍵接口:NamespaceHandlerSupport,BeanDefinitionParser
先看下基本工程代碼結構:

這裏寫圖片描述
①spring.schemas是告訴spring容器我們的自定義的xsd文件在哪裏,內容如下
這裏寫圖片描述
類似與key=value的形式。如果找不到會去網絡上下載。

②我們知道DTD與XSD是spring中最常見的切基礎的配置文件,打個比方DTD類似於Java的關鍵字,而XSD則類似於Java的語法。
而我們自定義XSD文件則是對於我們定義bean對象時可以使用的屬性限制或者說支持的那些屬性配置,自定義的spring-custom.xsd如下:
這裏寫圖片描述
指定namespace時,請勿使用spring默認前綴。
這裏我們定義了一個element屬性可以設置id,pointcut.

③Handlers作爲自定義標籤解析的入口需要在默認文件名稱spring.handlers指定,文件內容如下:

這裏是我們自定義的NamespaceHandlers.目的是爲了註冊我們對應標籤的解析類;
這裏寫圖片描述
④BeanDefinitionParser
這裏我們不直接實現這個接口,我們直接使用他的抽象實現類AbstractSingleBeanDefinitionParser。這裏我們獲取屬性並設置到bean中。
這裏寫圖片描述
這裏寫圖片描述

⑤自定義標籤的使用
這裏寫圖片描述
⑥工程代碼
點這裏
⑦Aop及tx也是通過自定義標籤來擴展容器能力的
AOP擴展解析入口爲AopNamespaceHandlers
這裏寫圖片描述
聲明式事務tx解析入口爲:TxNamespaceHandler
這裏寫圖片描述
Context解析入口爲:ContextNamespaceHandler
這裏寫圖片描述
以上我們都可以看到我們配置的屬性代碼中對應的BeanDefinitionParser

3.自定義標籤如何被spring解析


    這裏涉及到整個spring容器對於xml文件的解析過程,理解起來可能會有點困難,但我會盡量給大家做通俗易懂的介紹。
我們只介紹spring對於配置文件的解析過程,不介紹bean對象的實例化,初始化,及管理過程。

    我們先介紹幾個基礎知識
①我們經常說的spring容器到底指什麼,以及如何存儲我們配置bean屬性?
基礎容器BeanFactory,擴展容器ApplicationContext,他們解析配置文件的過程基本相同。
存儲結構爲Map<beanName, BeanDefinition>實現爲ConcurrentHashMap,也就是說我們最終解析出來的xml文件的會存儲到這個數據結構中,這就是我們的容器。

②我們解析出配置問文件用哪個對象來接收存儲?
我們知道在抽象對象世界裏everything is object.所以我們將bean抽象成了對象,它的頂層接口就是BeanDefinition,而子類包括了ChildBeanDefinitionRootBeanDefinitionGenericBeanDefinition,默認文件解析入Map爲GenericBeanDefinition.

③Spring基礎標籤有哪些?
這裏寫圖片描述
Import, alias, bean, beans

④Spring配置文件的解析入口在哪?
這裏介紹兩個重要的接口及其實現類
BeanDefinitionReaderBeanDefinitionDocumentReader
對應實現類XmlBeanDefinitionReaderDefaultBeanDefinitionDocumentReader
這裏寫圖片描述
這裏寫圖片描述
⑤自定義標籤的解析過程
這裏寫圖片描述
這裏最關鍵的步驟是DefaultBeanDefinitionDocumentReader類中私有方法

這裏寫圖片描述
    上圖即顯示了默認標籤和自定義標籤的不同解析方式。
    而自定義標籤的解析需要藉助Delegates獲取namespaceuri然後,加載我們配置的spring.handlers文件內容,獲取我們指定好的NamespaceHandler,然後調用parse方法初始化的init方法將BeanDefinitionParser初始化到parsers類型爲map容器中,然後我們根據localName獲取對應的BeanDefinitionParser,進行element的進一步解析。

    這個過程就完成了自定義標籤的文件的解析了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章