談談spring如何自定義標籤

乾貨點

瞭解如何基於spring自定義標籤,這是自定義組件的第一步。而最重要的是瞭解了這個過程後也能夠大體瞭解spring自身部分組件是怎麼相互工做和觸發的,如spring-aop,組件能夠經過反調AopNamespaceHandler瞭解大體面貌。java

系列文描述

書寫該系列文的初衷是由於最近正在負責一個組件的開發,因而打算將接觸和學習到的知識寫進博客裏。這第一篇,記錄基於spring如何自定義標籤。git

自定義標籤的做用

自定義標籤能夠說是spring爲了給相似你我這樣的開發人員擴展組件使用的,由於它提供了一個標準的公共可插拔的接口;目前咱們都知道spring很是強大,不過實際上除了spring-core和spring-beans外,其餘都是經過自定義標籤擴展實現的,其次還有一些開源組件也是,如dubbo等。因此,對於想擴展spring組件的小夥伴來講,瞭解如何自定義標籤和相應的原理是必須走的第一步。github

那麼如何自定義標籤

自定義標籤能夠簡單分爲四個步驟,分別是spring

  • 編寫.schemas文件,通知spring容器咱們定義的xsd文件在哪裏;
  • 編寫.xsd文件,定義配置時可使用的屬性限制或者說支持的那些屬性配置;
  • 編寫.handlers 文件,擴展NamespaceHandler命名空間註冊器和定義解析器;
  • 在xml文件中使用自定義標籤

下面我將以目前開發組件中的代碼作例子,從在xml文件中使用開始一步一步逆推,覆盤整個自定義標籤的過程。網絡

首先,先看下目錄狀況app

resource組件.png

common是我自定義的一個組件組,其中包含的resource組件即是此次使用了自定義標籤的主體,能夠從截圖中看出部分相關文件的存放位置。函數

test-demo.png

test-demo是爲了測試此次組件中的自定義標籤是否有做用而存在,test-demo只是導入了common組件組而已,再從中調用resource組件。好了,目錄結構描述完了,接下來進入正題。微服務

看下xml文件如何使用自定義標籤源碼分析

applicationContext.xml.png

在第4行這裏引入了resource對應的命名空間,spring會從本地掃.handlers,從中找到對應的Key值和Value值,如學習

spring.handlers.png

spring容器會將Key值對應的具體命名空間註冊註冊入容器,至於這個空間註冊器是怎麼樣的,後面再表,繼續描述xml文件。
在以後,咱們能夠在xmlns:schemaLocation中找到相似的Key&Value的配置,此次的配置是告訴spring容器從哪裏查找XSD文件,這點能夠從第六行找到,對應的XSD文件地址是:
http://www.nuofankj.com/resou...
細心的話不難發現,這是一個網絡地址,是的,確實如此,不過spring的容器倒是先在本地掃.schemas文件,而且讀取其中的鍵值對關係,從中找到本地的文件地址,若是找不到,纔會從網絡中讀取。如spring.schemas文件:

spring.schemas.png

該文件以一種鍵值對的形式代表了文件在本地的地址,那就是resource.xsd,以後spring容器便會找到resource.xsd文件作校驗。如

resource.xsd.png
resource.xsd.png

衆所周知,XSD文件的做用是定義配置時可使用的屬性限制或者說支持那些屬性配置。咱們能夠直接看applicationContext.xml中的配置

applicationContext.xml.png

走到這一步就說明配置文件配置好了,接下來即是如何解析的問題了。也就是上文提到com.nuofankj.resource.schema.NamespaceHandler

那麼NamespaceHandler類是什麼樣的

NamespaceHandler.java.png

該類擴展自NamespaceHandlerSupport,目的是將組件註冊到Spring容器中。其中以SchemaNames.CONFIG_ELEMENT爲名註冊了一個類ConfigDefinitionParserSchemaNames.CONFIG_ELEMENT對應的變量就是config字符串,目的就是爲了解析

config.png

顯然,ConfigDefinitionParser就是做爲解析器存在的。

接下來看看該解析器是什麼樣的

ConfigDefinitionParser.png

該解析器繼承了AbstractBeanDefinitionParser類,而且重寫parseInternal方法,其中的參數element攜帶了resource:config中的全部配置,咱們能夠將自身的解析業務放在該函數中。以我自定義的組件爲例:

AbstractBeanDefinitionParser.png

我這邊的業務是將SchemaNames.PACKAGE_ELEMENT包下的全部類掃出來而且放入list中保存,已經讀取出type、suffix等相關配置。

到這一步,自定義標籤的過程就所有理清楚了。
相關源碼地址:https://github.com/wiatingpub...


Java源碼分析、go語言應用、微服務,更多幹貨歡迎關注公衆號:
公衆號.jpg

相關文章
相關標籤/搜索