可扩展的XML Schema机制

从Spring2.0开始,Spring提供了XML Schema可扩展机制,用户可以自定义XML Schema文件,并自定义XML Bean解析器,并集成到Spring Ioc 容器中

完成XML自定义扩展,需要下面几个步骤:

  • 创建一个 XML Schema 文件,描述自定义的合法构建模块,也就是xsd文件

  • 自定义个处理器类,并实现NamespaceHandler接口(比较容易)

  • 自定义一个或多个解析器,实现BeanDefinitionParser接口(最关键的部分)

  • 注册上面的组件到Spring IOC容器中

按照上面的步骤,实现如下可扩展XML元素


<myns:dateformat id="dateFormat" pattern="yyyy-MM-dd HH:mm" />

可通过这种方式定义SimpleDateFormat

类似


<bean id="dateFormat" class="java.text.SimpleDateFormat"> <constructor-arg value="yyyy-HH-dd HH:mm"/> </bean>

1.自定义 XML Schema 文件

XML Schema 介绍


<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns="http://www.lh.com/schema/myns" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans" targetNamespace="http://www.lh.com/schema/myns" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xsd:import namespace="http://www.springframework.org/schema/beans"/> <xsd:element name="dateformat"> <xsd:complexType> <xsd:complexContent> <xsd:extension base="beans:identifiedType"> <xsd:attribute name="pattern" type="xsd:string" use="required"/> </xsd:extension> </xsd:complexContent> </xsd:complexType> </xsd:element> </xsd:schema>

其中自定义的命名空间是http://www.lh.com/schema/myns,定义了dateformat元素,属性有pattern

2.自定义 NamespaceHandler

定义好XML Schema文件,需要定义一个NamespaceHandler解析配置文件。

NamespaceHandler接口是非常简单的,只有三个方法:

  • init(): NamespaceHandler被使用之前调用,完成NamespaceHandler的初始化

  • BeanDefinition parse(Element, ParserContext): 当遇到顶层元素时被调用

  • BeanDefinition decorate(Node,BeanDefinitionHandler,ParserContext): 当遇到一个属性或者嵌套元素的时候调用

Spring提供了一个默认的实现类NamespaceHandlerSupport,我们只需要在init的时候注册每个元素的解析器即可。


public class DateformatNamespaceHandler extends NamespaceHandlerSupport { public void init() { registerBeanDefinitionParser("dateformat", new DeteformatDefinitionParser()); } }

这里实际用到了代理委托的概念,NamespaceHandlerSupport可以注册任意个BeanDefinitionParser。NamespaceHandlerSupport负责所有自定义元素的编排,而解析XML的工作委托给各个BeanDefinitionParser负责。

3.自定义BeanDefinitionParser

BeanDefinitionParser 将被调用,如果NamespapceHandler遇到元素类型已经有对应注册的parser(例如上面的handler如果遇到dateformat,DateformatDefinitionParser会被调用,解析相应的属性设置到Bean中)将会被调用。BeanDefinitionParser负责解析一个顶级元素。

Spring提供了AbstractSingleBeanDefinitionParser来处理繁重的解析工作,只需要实现两个方法:

  • Class<?> getBeanClass(Element):返回元素的Class类型

  • void doParse(Element element,BeanDefinitionBuilder builder):添加元素的属性或者构造参数等等


package com.lh.spring; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; import org.w3c.dom.Element;import java.text.SimpleDateFormat; public class DateformatDefinitionParser extends AbstractSingleBeanDefinitionParser { @Override protected Class<?> getBeanClass(Element element) { return SimpleDateFormat.class; } @Override protected void doParse(Element element, BeanDefinitionBuilder builder) { String pattern = element.getAttribute("pattern"); builder.addConstructorArgValue(pattern); } }

4.注册handler和schema

为了让Spring在解析xml的时候能够感知到我们的自定义元素,我们需要把namespaceHandler和xsd文件放到2个指定的配置文件中,这2个文件都位于META-INF目录中

4.1spring.handlers文件包含了xml schema uri 和 Handler类的映射关系,例如


http\://www.lh.com/schema/myns=com.lh.spring.DateformatNamespaceHandler

遇到http://www.lh.com/schema/myns名空间的时候会交给CarNamespaceHandler来处理,key部分必须和xsd文件中的targetNamespace值保持一致

4.2 spring.schemas文件包含了xml schema xsd文件命名空间和文件路径的映射关系,例如


http\://www.lh.com/schema/myns.xsd=META-INF/com.lh.date.format/sfm-1.0.xsd

5.实践测试

5.1 加入Spring配置文件:


<?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:my="http://www.lh.com/schema/myns" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.lh.com/schema/myns http://www.lh.com/schema/myns.xsd"> <my:dateformat id="dateformat" pattern="yyyy-MM-dd HH:mm" /> </beans>

5.2 单元测试:

全部代码


package com.lh.spring; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:spring/application-core.xml"}) public class XMLSchemaCustomTest { @Autowired private SimpleDateFormat dateFormat; @Test public void propertyTest() { Assert.assertNotNull(dateFormat); String date = "2010-10-10 11:12:14"; SimpleDateFormat ymdhms = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { Date time = ymdhms.parse(date); String dateFormatStr = dateFormat.format(time); Assert.assertTrue("2010-10-10 11:12".equals(dateFormatStr)); } catch (ParseException e) { e.printStackTrace(); } } }

Spring可扩展的XML Schema机制的更多相关文章

  1. 7 -- Spring的基本用法 -- 11... 基于XML Schema的简化配置方式

    7.11 基于XML Schema的简化配置方式 Spring允许使用基于XML Schema的配置方式来简化Spring配置文件. 7.11.1 使用p:命名空间简化配置 p:命名空间不需要特定的S ...

  2. 从零开始学spring源码之xml解析(二):默认标签和自定义标签解析

    默认标签: 上一篇说到spring的默认标签和自定义标签,发现这里面东西还蛮多的.决定还是拆开来写.今天就来好好聊聊这两块是怎么玩的,首先我们先看看默认标签: private void parseDe ...

  3. 缘起 Dubbo ,讲讲 Spring XML Schema 扩展机制

    背景 在 Dubbo 中,可以使用 XML 配置相关信息,也可以用来引入服务或者导出服务.配置完成,启动工程,Spring 会读取配置文件,生成注入 相关 Bean.那 Dubbo 如何实现自定义 X ...

  4. 聊聊 Spring 的 XML Schema 扩展机制的使用方式

    前言 在当前Java生态,Spring算的上是最核心的框架,所有的开发组件想要得到大范围更便捷的使用,都要和Spring进行整合,比如我们熟知的Mybatis.Dubbo等,以及内部封装的各类组件包括 ...

  5. dubbo源码之一——xml schema扩展

    dubbo源码版本:2.5.4 dubbo-parent |----dubbo-config |----dubbo-config-api |----com.alibaba.dubbo.config.* ...

  6. Spring可扩展Schema标签

    基于Spring可扩展Schema提供自己定义配置支持 http://blog.csdn.net/cutesource/article/details/5864562 WARN : org.sprin ...

  7. onfiguration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/security]

    org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Una ...

  8. spring 与 CXF 整合 webservice 出现error “Unable to locate Spring NamespaceHandler for XML schema namespace” 总结

    我试了多个版本的spring 发现 出现error : Unable to locate Spring NamespaceHandler for XML schema namespace 并非都是sp ...

  9. Spring 3.0: Unable to locate Spring NamespaceHandler for XML schema namespace

    被这个问题折磨着很久:参考: http://have23.iteye.com/blog/1340777 (cfx 与 spring 整合的时候出现的问题: org.springframework.be ...

随机推荐

  1. LESS,强大的CSS预处理语言

    虽然写的css不多,但是我已经切身感觉到了书写css的恶心...抛开最令人烦的浏览器兼容问题不说,这个语言本身就有不少问题. 最简单的,比如多个地方是同一个颜色的,如果可以写在一个样式里还没什么,但是 ...

  2. Nginx部署前端代码实现前后端分离

    实现前后端分离,可以让前后端独立开发.独立部署.独立单测,双方通过JSON进行数据交互. 对于前端开发人员来说,不用每次调试都需要启动或配置Java/Tomcat运行环境:对于后端开发人员来说 ,也不 ...

  3. python读取中文

    如何从文件中读取300个汉字? 看起来很简单,但很容易掉坑里了. 一开始我这么写: try: fd = codecs.open(os.path.join(settings.TEXT_CONTENT_D ...

  4. 转: codereview 工具平台建设

    一.  Rietveld  code review  (一套工具系统与平台) 1. http://www.cnblogs.com/fang9159/archive/2012/07/20/2591690 ...

  5. 转:mac 设置root 密码

    终端中输:sudo passwd rootpasswd root是修改root的命令,unix下sudo是以当前用户的身份执行root的命令,以避免输入root的密码但是sudo依赖于配置文件/etc ...

  6. 抓取网页图片的脚本(javascript)

    抓取网页图片的脚本(javascript) 本文地址: http://blog.csdn.net/caroline_wendy/article/details/24172223 脚本内容 (没有换行) ...

  7. linux中mysql主从备份

    在centos中安装mysql详细步骤说明 条件:需要两个虚拟机,一台为主服务器master,一台为从服务器slave 1     在master主服务中,创建用于同步的用户 mysql> gr ...

  8. 倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-如何添加Scope监控

    添加一个Scope YT NC项目   默认添加的就是对Axis_1的监控,位置,速度和加速度都有,可以删除模长的监控(Position modulo)   点击Record就可以记录曲线了(要停止记 ...

  9. c# 句柄数不断攀升的解决方案

    句柄只是用来标识应用程序中的不同对象和同类中的不同的实例的一个数字,通常情况下,句柄值对普通用户毫无用处,但是句柄数量却可以间接反映出一个程序里产生的对象实例的多少.句柄数越多,代表程序里new 出来 ...

  10. CAS(Central Authentication Service)——windows上简单搭建及測试

    入手文章,大神绕行. 一.服务端搭建 我使用的服务端版本号为:cas-server-3.4.11-release.zip.解压之后,将\cas-server-3.4.11-release\cas-se ...