Spring 允許通過 Namespace 擴展定義專屬 XML 標簽,將複雜 Bean 定義簡化為語義化標簽。本文完整演示從 XSD 定義到 NamespaceHandler、BeanDefinitionParser 的實現全過程。
NamespaceHandler 實現類;BeanDefinitionParser;BeanDefinition 註冊到容器。<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="https://www.w3.org/2001/XMLSchema"
targetNamespace="https://test.hatter.me/schema/test"
xmlns="https://test.hatter.me/schema/test"
elementFormDefault="qualified">
<xsd:element name="custom">
<xsd:complexType>
<xsd:attribute name="id" type="xsd:ID"/>
<xsd:attribute name="name" type="xsd:string"/>
</xsd:complexType>
</xsd:element>
</xsd:schema>
http\://test.hatter.me/schema/test/test.xsd=META-INF/test.xsd
http\://test.hatter.me/schema/test=me.hatter.test.TestNamespaceHandler
public class TestNamespaceHandler extends NamespaceHandlerSupport {
@Override public void init() {
registerBeanDefinitionParser("custom", new TestCustomBeanDefinitionParser());
}
}
public class TestCustomBeanDefinitionParser implements BeanDefinitionParser {
@Override public BeanDefinition parse(Element element, ParserContext ctx) {
String id = element.getAttribute("id");
String name = element.getAttribute("name");
RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
bd.getPropertyValues().addPropertyValue("name", name);
ctx.getRegistry().registerBeanDefinition(id, bd);
return bd;
}
}
<beans xmlns:test="https://test.hatter.me/schema/test"
xsi:schemaLocation="...
https://test.hatter.me/schema/test https://test.hatter.me/schema/test/test.xsd">
<test:custom id="testCustom" name="this is a test custom tag"/>
</beans>
ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:me/hatter/test/main/test.xml");
System.out.println(ctx.getBean("testCustom")); // TestBean[name=this is a test custom tag]