某些情况下,为了给业务系统提供可配置化支持,我们一般会用原生态的方式去解析定义好的XML文件,然后转化为配置对象。这种方式对于简单、单一的配置文件,或者是XML配置格式固定的配置文件,还是比较容易处理的。但是对于一些复杂的、对可扩展性、灵活性要求比较高的场景,使用这种方式去验证、解析就会比较麻烦了。针对这种情况,Spring提供了对用户扩展Schema的支持,这样就可以使用Spring已有的验证、解析工具进行自定义标签的处理了。

  扩展Spring自定义标签配置还是比较简单的,大致需要以下几个步骤:

  1. 创建一个需要扩展的组件类
  2. 定义一个XSD文件,描述组件内容
  3. 创建一个类,实现BeanDefinitionParser接口,用来解析XSD文件中的各种定义以及组件定义
  4. 创建一个Handler类,并继承NamespaceHandlerSupport类,目的是将组件注册到Spring容器
  5. 编写spring.schemas和spring.handlers文件分别指定parser与handler,spring默认会通过这两个文件找到BeanDefinitionParser与NamespaceHandlerSupport

下边通过一个简单的示例来展示一下如何创建一个自定义的标签。

  1. 创建一个普通的POJO类

    public class User {
    private String userName;
    private String email;
    public String getUserName() {
    return userName;
    }
    public void setUserName(String userName) {
    this.userName = userName;
    }
    public String getEmail() {
    return email;
    }
    public void setEmail(String email) {
    this.email = email;
    }
    }
  2. 定义一个XSD文件,用来描述组件内容
    <?xml version="1.0" encoding="UTF-8"?>
    <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/schema/user" xmlns:tns="http://www.example.org/schema/user" elementFormDefault="qualified">
    <element name="user">
    <complexType>
    <attribute name="id" type="string"></attribute>
    <attribute name="userName" type="string"></attribute>
    <attribute name="email" type="string"></attribute>
    </complexType>
    </element>
    </schema>

    将XSD文件放在src/main/resources/META-INF下,名称为spring-test.xsd

  3. 创建一个类,实现BeanDefinitionParser接口,用来解析XSD文件中的各种定义和组件定义
    public class UserBeanDefinitionParser extends AbstractSingleBeanDefinitionParser{
    
        @Override
    protected Class<?> getBeanClass(Element element){
    return User.class;
    } @Override
    protected void doParse(Element element, BeanDefinitionBuilder bean){
    String userName = element.getAttribute("userName");
    String email = element.getAttribute("email");
    if(StringUtils.hasText(userName)){
    bean.addPropertyValue("userName", userName);
    }
    if(StringUtils.hasText(email)){
    bean.addPropertyValue("email", email);
    }
    }
    }
  4. 创建一个Handler类,并继承NamesapceHandlerSupport,目的是将组件注册到Spring容器
    public class MyNamespaceHandlerSupport extends NamespaceHandlerSupport{
    @Override
    public void init() {
    registerBeanDefinitionParser("user", new UserBeanDefinitionParser());
    }
    }
  5. 目前spring还无法加载我们这些自定义的东西,还需要让spring能够找到并加载我们自定义的东西,这个时候就要用到spring.handlers和spring.schemas文件,因为spring会默认查找src/main/resources/META-INF目录下的这两个文件,来检查是否有用户自定义的标签。
    • spring.schemas

      http\://www.example.org/schema/user.xsd=META-INF/spring-test.xsd
    • spring.handlers
      http\://www.example.org/schema/user=chapter04.MyNamespaceHandlerSupport

下边测试一下我们自定义的标签

  1. 创建测试的xml配置文件

    <?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:myname="http://www.example.org/schema/user"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.example.org/schema/user http://www.example.org/schema/user.xsd">
    <myname:user id="testbean" userName="aaa" email="bbb" />
    </beans>

    这里的过程是,注意第四行“xmlns:myname”,当遇到myname开头的标签时,就会通过xmlns:myname="http://www.example.org/schema/user"找到该标签的命名空间为"http://www.example.org/schema/user",然后通过spring.handlers找到对应的该命名空间的handler为chapter04.MyNamespaceHandlerSupport,然后将名字为user的子标签交由UserBeanDefinitionParser对象进行处理。当需要对xml的元素进行验证时,通过第七行可以找到命名空间对应的xsd的名称http://www.example.org/schema/user.xsd,然后通过spring.schemas找到实际的xsd文件对应的位置META-INF/spring-test.xsd,通过spring-test.xsd对元素进行校验。

  2. 创建测试类
    public class Test {
    public static void main(String[] args) {
    ApplicationContext ac = new ClassPathXmlApplicationContext("beanFactoryTest.xml");
    User user = (User)ac.getBean("testbean");
    System.out.println(user.getUserName() + "," + user.getEmail());
    }
    }

spring中的自定义标签的更多相关文章

  1. 在jsp页面中使用自定义标签

    在某些场景中,自定义标签可封装大量代码,使页面变得更简洁,标签也可以很方便地在不同页面中实现通用而不必去粘贴大量的js代码.现在把最近做的一个自定义标签在这里总结一下.首先总结一下关于自定义标签的一些 ...

  2. springbank 开发日志 Spring启动过程中对自定义标签的处理

    这篇随笔的许多知识来源于:http://www.importnew.com/19391.html 之所以会去看这些东东,主要是希望能够模仿spring mvc的处理流程,做出一套合理的交易处理流程. ...

  3. Spring源码分析(九)解析默认标签中的自定义标签元素

    摘要:本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 到这里我们已经完成了分析默认标签的解析与提取过程,或许涉及的内容太多,我 ...

  4. spring源码-自定义标签-4

    一.自定义标签,自定义标签在使用上面相对来说非常常见了,这个也算是spring对于容器的拓展.通过自定义标签的方式可以创造出很多新的配置方式,并且交给容器直接管理,不需要人工太多的关注.这也是spri ...

  5. 在django中使用自定义标签实现分页功能

    效果演示: github地址:https://github.com/mncu/django_projects/tree/master/django_projects/pagination_test 本 ...

  6. javaWeb 在jsp中 使用自定义标签输出访问者IP

    1.java类,使用简单标签,jsp2.0规范, 继承 SimpleTagSupport public class ViewIpSimpleTag extends SimpleTagSupport { ...

  7. spring整合freemarker 自定义标签

    1.自定义标签实现 TemplateDirectiveModel 接口 2.spring 配置,注意标红的两行 <bean id="freemarkerConfig" cla ...

  8. Spring中的p标签(转)good

    Spring的p标签是基于XML Schema的配置方式,目的是为了简化配置方式. 在XML文件头部添加xmlns:p="http://www.springframework.org/sch ...

  9. spring中增加自定义配置支持

    spring.schemas 在使用spring时,我们会首先编写spring的配置文件,在配置文件中,我们除了使用基本的命名空间http://www.springframework.org/sche ...

随机推荐

  1. 本地连接 vmware服务器

    在本机中装载虚拟机,安装redhat.需要调试使用redhat可以与Windows进行通讯. 分为多步,在此前提下,默认你已经安装好且可以vm 和虚拟机 1:点击虚拟机>设置>添加网络适配 ...

  2. 实现ajax的步骤

    实现ajax的步骤 1.创建xmlHttprequest对象 function createXmlHttpRequest(){ var xmlHttp; try{ //Firefox, Opera 8 ...

  3. 版本控制之二:SVN的初步使用(转)

    转自http://www.cnblogs.com/xiaobaihome/archive/2012/03/20/2407979.html 上一篇介绍了VisualSVN Server和Tortoise ...

  4. android开发第一天

    今天可以说是我正式投入android怀抱的第一天吧,按着自己的兴趣,努力地吸取知识.听了程老师的课,也觉得收获很多,毕竟以前都是看着书本或者网页教程来学习,第一次有人这么直接地跟你教授着,说着一些你听 ...

  5. linux学习(一)认识、安装Linux

    一.什么是Linux linux是一种操作系统,我们用的android和ios就是分别是linux操作系统和类unix操作系统. linux也是我们经常说的服务器.我们看的网站,游戏,app背后都是服 ...

  6. Hello Kiki(中国剩余定理——不互质的情况)

    Hello Kiki Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  7. 脑残手贱:被NFS祸害的调度系统

    建议:任何时候,都要三思而后行!!! 事请的缘由 系统中采用slurm调度系统来进行并行计算.但是在GPU节点上,无论如何都无法启动slurmd,报插件初始化错误的故障. 因此需要编译新的munge和 ...

  8. 软硬链接、文件删除原理、linux中的三种时间、chkconfig优化

    第1章 软硬链接 1.1 硬链接 1.1.1 含义 多个文件拥有相同的inode号码 硬链接即文件的多个入口 1.1.2 作用 防止你误删除文件 1.1.3 如何创建硬链接 ln 命令,前面是源文件  ...

  9. 0_Simple__matrixMulDrv

    使用CUDA的 Driver API 来计算矩阵乘法. ▶ 源代码: #include <stdio.h> #include <cuda.h> #include <bui ...

  10. 【DG】利用闪回数据库(flashback)修复Failover后的DG环境

    利用闪回数据库(flashback)修复Failover后的DG环境 1.1  BLOG文档结构图 1.2  前言部分 1.2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能, ...