Spring可扩展的XML Schema机制
可扩展的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 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机制的更多相关文章
- 7 -- Spring的基本用法 -- 11... 基于XML Schema的简化配置方式
		7.11 基于XML Schema的简化配置方式 Spring允许使用基于XML Schema的配置方式来简化Spring配置文件. 7.11.1 使用p:命名空间简化配置 p:命名空间不需要特定的S ... 
- 从零开始学spring源码之xml解析(二):默认标签和自定义标签解析
		默认标签: 上一篇说到spring的默认标签和自定义标签,发现这里面东西还蛮多的.决定还是拆开来写.今天就来好好聊聊这两块是怎么玩的,首先我们先看看默认标签: private void parseDe ... 
- 缘起 Dubbo ,讲讲 Spring XML Schema 扩展机制
		背景 在 Dubbo 中,可以使用 XML 配置相关信息,也可以用来引入服务或者导出服务.配置完成,启动工程,Spring 会读取配置文件,生成注入 相关 Bean.那 Dubbo 如何实现自定义 X ... 
- 聊聊 Spring 的 XML Schema 扩展机制的使用方式
		前言 在当前Java生态,Spring算的上是最核心的框架,所有的开发组件想要得到大范围更便捷的使用,都要和Spring进行整合,比如我们熟知的Mybatis.Dubbo等,以及内部封装的各类组件包括 ... 
- dubbo源码之一——xml schema扩展
		dubbo源码版本:2.5.4 dubbo-parent |----dubbo-config |----dubbo-config-api |----com.alibaba.dubbo.config.* ... 
- Spring可扩展Schema标签
		基于Spring可扩展Schema提供自己定义配置支持 http://blog.csdn.net/cutesource/article/details/5864562 WARN : org.sprin ... 
- 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 ... 
- 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 ... 
- Spring 3.0: Unable to locate Spring NamespaceHandler for XML schema namespace
		被这个问题折磨着很久:参考: http://have23.iteye.com/blog/1340777 (cfx 与 spring 整合的时候出现的问题: org.springframework.be ... 
随机推荐
- 二、spring-boot文件配置
			项目文件结构,新建的Springboot项目的文件结构如下: |-customer(项目名称) | - sec | | - main | | | - java | | | - resources | ... 
- iOS:Reachability网络监听
			iOS利用Reachability确认网络环境3G/WIFI 开发Web等网络应用程序的时候,需要确认网络环境,连接情况等信息.如果没有处理它们,是不会通过Apple的审查的,一般情况下,可以把网络监 ... 
- TensorFlow------TFRecords的读取实例
			TensorFlow------TFRecords的读取实例: import os import tensorflow as tf # 定义cifar的数据等命令行参数 FLAGS = tf.app. ... 
- ISP图像调试工程师——自动曝光(熟悉3A算法)
			基于图像的自动曝光算法研究 : https://wenku.baidu.com/view/c854fa93fd0a79563c1e72ba.html 
- 贯通Spark Streaming JobScheduler内幕实现和深入思考
			本节主要内容: 一.SparkStreaming Job生成深度思考 二.SparkStreaming Job生成源码解析 JobScheduler的地位非常的重要,所有的关键都在JobSchedul ... 
- YARN Application执行流程
			原文见 http://xiguada.org/yarn-application_run/ 本节简单描述了一个Application在YARN上的执行流程,希望对初识YARN的同学提供一些帮助. 图1 ... 
- decorator在Python中的作用
			decorator(装饰器)在python中作用,可以起到代码复用,也可以起到AOP(面向横切面)的作用. 另外很重要的一点应该就是function在python的世界中是作为一等公民存在的. 在py ... 
- 接口测试框架开发(一):rest-Assured_接口返回数据验证
			转载:http://www.cnblogs.com/lin-123/p/7111034.html 返回的json数据:{"code":"200","m ... 
- 实现淡入淡出效果的组件,继承自JComponent
			由于仅贴出代码,供有缘人参考. import java.awt.AlphaComposite; import java.awt.Graphics; import java.awt.Graphics2D ... 
- docker学习笔记-1
			docker学习笔记一:安装 mac安装docker docker官方文档上有这么一段话: Because the Docker daemon uses Linux-specific kernel f ... 
