当Spring拿到一个元素时首先要做的是根据命名空间进行解析,如果是默认的命名空间,则使用parseDefaultElement方法进行元素解析,否则使用parseCustom Element方法进行解析。

    protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
parseDefaultElement(ele, delegate);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
} public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
String namespaceUri = getNamespaceURI(ele);
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler == null) {
error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
return null;
}
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}

自定义标签的使用

扩展Spring自定义标签配置大致需要以下几个步骤(前提是要把Spring的Core包加入项目中)。

  1. 创建一个需要扩展的组件。
  2. 定义一个XSD文件描述组件内容。
  3. 创建一个文件,实现BeanDefinitionParser接口,用来解析XSD文件中的定义和组件定义。
  4. 创建一个Handler文件,扩展自NamespaceHandlerSupport,目的是将组件注册到Spring容器。
  5. 编写Spring.handlers和Spring.schemas文件。

现在我们就按照上面的步骤一步步地体验自定义标签的过程。

第一步:

public class TestBean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "TestBean{" +
"name='" + name + '\'' +
'}';
}
}

第二步:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://code.alibabatech.com/schema/dubbo"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://code.alibabatech.com/schema/dubbo"> <xsd:element name="custom" type="customType">
</xsd:element>
<xsd:complexType name="customType">
<xsd:attribute name="id" type="xsd:ID">
</xsd:attribute>
<xsd:attribute name="name" type="xsd:string">
</xsd:attribute>
</xsd:complexType> </xsd:schema>

第三步:

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element; public class TestCustomBeanDefinitionParser implements BeanDefinitionParser { public BeanDefinition parse(Element element, ParserContext parserContext) { String id = element.getAttribute("id");
String name = element.getAttribute("name"); RootBeanDefinition beanDefinition = new RootBeanDefinition();
beanDefinition.setBeanClass(TestBean.class);
beanDefinition.getPropertyValues().addPropertyValue("name", name);
parserContext.getRegistry().registerBeanDefinition(id, beanDefinition); return beanDefinition;
}
}

第四步:

import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
public class TestNamespaceHandler extends NamespaceHandlerSupport {
public void init() {
registerBeanDefinitionParser("custom", new TestCustomBeanDefinitionParser());
}
}

第五步:

spring.handlers:
http\://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler
spring.schemas:
http\://code.alibabatech.com/schema/dubbo/dubbo.xsd=META-INF/dubbo.xsd

第六步:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <dubbo:custom id="testCustom" name="this is a test custom tag" />
</beans> import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) {
String xml = "classpath:test.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] { xml });
System.out.println(context.getBean("testCustom"));
}
} 上例输出为:
TestBean {name=this is a test custom tag}

最新文章

  1. 剑指Offer面试题:6.用两个栈实现队列
  2. 使用 HTML5 WebGL 实现逼真的云朵效果
  3. ios -- 教你如何轻松学习Swift语法(三) 完结篇
  4. ansible管理
  5. SAP BW顾问如何保持市场竞争力
  6. AnimationDrawable 资源
  7. [翻译] Tensorflow模型的保存与恢复
  8. ajax核心技术1---XMLHttpRequset对象的使用
  9. html5学习之旅-html5的简易数据库开发(18)
  10. 《JavaScript高级程序设计》笔记:变量、作用域和内存问题(四)
  11. zabbix全网监控
  12. typescript interface 泛型
  13. js生成的cookie在yii2中获取不到的解决办法
  14. Linux双线双网卡双IP双网关设置方法
  15. 【xsy2332】Randomized Binary Search Tree DP+FFT
  16. Linux下配置自动更新时间
  17. VGG 论文研读
  18. [Windows Azure] Windows Azure Identity
  19. 【Python学习】记一次开源博客系统Blog_mini源码学习历程-Flask
  20. cocos2dx中调用TinyXml读取xml配置文件 || cocos2d-x 中跨平台tinyxml读取xml文件方式

热门文章

  1. 使用node.js制作简易爬虫
  2. [Effective JavaScript 笔记]第38条:在子类的构造函数中调用父类的构造函数
  3. win7安装apache或者php 5.7缺少vcruntime140.dll的问题
  4. HDOJ 1233
  5. 利用nginx泛域名解析配置二级域名和多域名
  6. 使用XmlWriter写Xml
  7. CentOS 关闭蜂鸣器声音
  8. SQL按照指定顺序对字段进行排序
  9. Transfer-Encoding: chunked
  10. DP:Cheapest Palindrome(POJ 3280)