spring自定義標簽
Spring自定義標簽的原理
XML通常通過DTD、XSD定義,但DTD的表達能力較弱,XSD定義則能力比較強,能夠定義類型,出現次數等。自定義標簽需要XSD支持,在實現時使用Namespace擴展來支持自定義標簽。
當你在苦逼的寫下面的代碼時:
Xml代碼
XXXX XXXX
是不是會羨慕這樣寫代碼呢?
Xml代碼
Spring通過XML解析程序將其解析為DOM樹,通過NamespaceHandler指定對應的Namespace的BeanDefinitionParser將其轉換成BeanDefinition。再通過Spring自身的功能對BeanDefinition實例化對象。
在期間,Spring還會加載兩項資料:
META-INF/spring.handlers
指定NamespaceHandler(實現
org.springframework.beans.factory.xml.NamespaceHandler)接口,或使用
org.springframework.beans.factory.xml.NamespaceHandlerSupport的子類。
META-INF/spring.schemas
在解析XML文件時將XSD重定向到本地文件,避免在解析XML文件時需要上網下載XSD文件。通過現實
org.xml.sax.EntityResolver接口來實現該功能。
制作自定義的標簽
spring.handlers:
Xml代碼

http\://test.hatter.me/schema/test=me.hatter.test.TestNamespaceHandler
spring.schemas:
Xml代碼

http\://test.hatter.me/schema/test/test.xsd=META-INF/test.xsd
test.xsd:
Xml代碼

targetNamespace="http://test.hatter.me/schema/test">
me.hatter.test.TestNamespaceHandler:
Java代碼

packageme.hatter.test; importorg.springframework.beans.factory.xml.NamespaceHandlerSupport; publicclassTestNamespaceHandlerextendsNamespaceHandlerSupport{ publicvoidinit(){ registerBeanDefinitionParser("custom",newTestCustomBeanDefinitionParser()); } }
me.hatter.test.TestCustomBeanDefinitionParser:
Java代碼

packageme.hatter.test; importme.hatter.test.bean.TestBean; importorg.springframework.beans.factory.config.BeanDefinition; importorg.springframework.beans.factory.support.RootBeanDefinition; importorg.springframework.beans.factory.xml.BeanDefinitionParser; importorg.springframework.beans.factory.xml.ParserContext; importorg.w3c.dom.Element; publicclassTestCustomBeanDefinitionParserimplementsBeanDefinitionParser{ publicBeanDefinitionparse(Elementelement,ParserContextparserContext){ Stringid=element.getAttribute("id"); Stringname=element.getAttribute("name"); RootBeanDefinitionbeanDefinition=newRootBeanDefinition(); beanDefinition.setBeanClass(TestBean.class); beanDefinition.getPropertyValues().addPropertyValue("name",name); parserContext.getRegistry().registerBeanDefinition(id,beanDefinition); returnbeanDefinition; } }
測試代碼
test.xml:
Xml代碼

xmlns:test="http://test.hatter.me/schema/test" xsi:schemaLocation=" http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://test.hatter.me/schema/testhttp://test.hatter.me/schema/test/test.xsd">
me.hatter.test.main.Main:
Java代碼

packageme.hatter.test.main; importorg.springframework.context.ApplicationContext; importorg.springframework.context.support.ClassPathXmlApplicationContext; publicclassMain{ publicstaticvoidmain(String[]args){ Stringxml="classpath:me/hatter/test/main/test.xml"; ApplicationContextcontext=newClassPathXmlApplicationContext(newString[]{xml}); System.out.println(context.getBean("testCustom")); } }
上例輸出為:
TestBean[name=thisis a test custom tag]