zoukankan      html  css  js  c++  java
  • spring 定义自己的标签 学习

    自己的自定义配置文件spring 在,有时你想要做一些配置信息的数据结构。基于扩展生意做。

    首先:

    在项目META-INF文件夹中创建两个文件spring.handlers,和spring.shcemas

    Spring.handlers在类org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver中已经写死了要取mapping的handlerMappingsLocation的路径

    public static finalString DEFAULT_HANDLER_MAPPINGS_LOCATION ="META-INF/spring.handlers";

    Spring.Schemas 在org.springframework.beans.factory.xml.PluggableSchemaResolver这个类中

    相同写死了位置

    public static finalString DEFAULT_SCHEMA_MAPPINGS_LOCATION = "META-INF/spring.schemas";

    初始化的时候第一次调用的时候会调用

    PropertiesLoaderUtils.loadAllProperties(this.schemaMappingsLocation,this.classLoader)

    把全部的文件名称包括的取出来放入map中。


    spring.handlers内容:

    http://www.ruishenh.com/custom/mytest=com.ruishenh.spring.config.MyNamespaceHandler


    spring.schemas内容:

    http://www.ruishenh.com/custom/mytest/myTest.xsd=customTag/myTest.xsd


    customTag/myTest.xsd文件:

     

    <?xml version="1.0"encoding="UTF-8"?>
    <xsd:schema xmlns="http://www.ruishenh.com/custom/myTest"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.ruishenh.com/custom/mytest"
        elementFormDefault="qualified" attributeFormDefault="unqualified">
        <xsd:element name="executor">
            <xsd:complexType>
                <xsd:attribute name="name" type="xsd:string">
                </xsd:attribute>
                <xsd:attribute name="delay" type="xsd:int">
                </xsd:attribute>
                <xsd:attribute name="interval" type="xsd:int"use="required">
                </xsd:attribute>
                <xsd:attribute name="address" type="xsd:string">
                </xsd:attribute>
                <xsd:attribute name="entity" type="xsd:string">
                </xsd:attribute>
            </xsd:complexType>
        </xsd:element>
        <xsd:element name="entity">
            <xsd:complexType>
                <xsd:attribute name="name" type="xsd:string">
                    <xsd:annotation>
                        <xsd:documentation><![CDATA[ bean Name ]]></xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
                <xsd:attribute name="splitBy" type="xsd:string">
                    <xsd:annotation>
                        <xsd:documentation xml:lang="zh"><![CDATA[ sqoop切割字段 ]]></xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
                <xsd:attribute name="sql" type="xsd:string">
                    <xsd:annotation>
                        <xsd:documentation xml:lang="zh"><![CDATA[数据库操作sql]]></xsd:documentation>
                    </xsd:annotation>
                </xsd:attribute>
                <xsd:attribute name="dbTypeID">
                    <xsd:annotation>
                        <xsd:documentation xml:lang="zh">
                        <![CDATA[ 指定数据库类型 假设类型不存在就推断dbTypeName属性,1是mysql。2是oracle,3是sqlserver    ]]>
                        </xsd:documentation>
                    </xsd:annotation>
                    <xsd:simpleType>
                        <xsd:restriction base="xsd:int">
                            <xsd:enumeration value="1" />
                            <xsd:enumeration value="2" />
                            <xsd:enumeration value="3" />
                        </xsd:restriction>
                    </xsd:simpleType>
                </xsd:attribute>
                <xsd:attribute name="dbTypeName">
                    <xsd:annotation>
                        <xsd:documentation xml:lang="zh"><![CDATA[ 指定数据库指定名称  假设  dbTypeID 不存在就取当前值 ]]></xsd:documentation>
                    </xsd:annotation>
                    <xsd:simpleType>
                        <xsd:restriction base="xsd:string">
                            <xsd:enumeration value="mysql" />
                            <xsd:enumeration value="oracle" />
                            <xsd:enumeration value="sqlserver" />
                        </xsd:restriction>
                    </xsd:simpleType>
                </xsd:attribute>
            </xsd:complexType>
        </xsd:element>
    </xsd:schema>

    spring/myTest.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:mi="http://www.ruishenh.com/custom/mytest" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.ruishenh.com/custom/mytesthttp://www.ruishenh.com/custom/mytest/myTest.xsd"> <mi:entity dbTypeID="1" dbTypeName="mysql"splitBy="id" sql="1" name="mye" /> <mi:executor interval="5000" address="127.0.0.1"delay="2000" name="myexecutor" entity="mye" /> </beans>



    com.ruishenh.spring.config.MyNamespaceHandler  命名空间处理类:

     

    package com.ruishenh.spring.config;
     
    import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
     
    public class MyNamespaceHandler extends NamespaceHandlerSupport{
     
        @Override
        public void init() {
            registerBeanDefinitionParser("executor",newMyBeanDefinitionParser(MyExecutor.class));
            registerBeanDefinitionParser("entity",newMyBeanDefinitionParser(MyEntity.class));
        }
     
    }

    这个类主要是在DefaultNamespaceHandlerResolver这个类中getHandlerMappings()取到了全部的META-INF/spring.handlers的文件内容存入map,然后依据当前的命名空间找到相应的NamespaceHandler,然后反射出对象调用init()

    Class<?> handlerClass =ClassUtils.forName(className, this.classLoader);
                    if (!NamespaceHandler.class.isAssignableFrom(handlerClass)){
                        throw new FatalBeanException("Class ["+ className + "] for namespace [" + namespaceUri +
                                "] does not implement the [" + NamespaceHandler.class.getName() + "] interface");
                    }
                    NamespaceHandlernamespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
                    namespaceHandler.init();
     
     


    com.ruishenh.spring.config.MyBeanDefinitionParser解析类:

     

    packagecom.ruishenh.spring.config;
     
    importorg.springframework.beans.factory.config.BeanDefinition;
    importorg.springframework.beans.factory.config.RuntimeBeanReference;
    importorg.springframework.beans.factory.support.RootBeanDefinition;
    importorg.springframework.beans.factory.xml.BeanDefinitionParser;
    importorg.springframework.beans.factory.xml.ParserContext;
    importorg.w3c.dom.Element;
    importorg.w3c.dom.NamedNodeMap;
    importorg.w3c.dom.Node;
     
    public classMyBeanDefinitionParser implements BeanDefinitionParser {
     
             private Class<?> clssze;
     
             publicMyBeanDefinitionParser(Class<?

    > cls) { this.clssze = cls; } @Override public BeanDefinition parse(Elementelement, ParserContext parserContext) { RootBeanDefinitionbeanDefinition = new RootBeanDefinition(); beanDefinition.setBeanClass(clssze); String id = null; id =element.getAttribute("name"); if (id == null) { if (clssze ==MyExecutor.class) { id = "test_myExecutor"; } else if (clssze ==MyEntity.class) { id ="test_myentity"; } else { throw newIllegalStateException("MyBeanDefinitionParser.parse,未知的业务逻辑处理:class:" +element.getAttribute("class")); } } int counter = 2; while(parserContext.getRegistry().containsBeanDefinition(id)) { id = id +(counter++); } if (id != null &&id.length() > 0) { if(parserContext.getRegistry().containsBeanDefinition(id)) { throw newIllegalStateException("Duplicate spring bean id " + id); } parserContext.getRegistry().registerBeanDefinition(id,beanDefinition); } NamedNodeMap nnm =element.getAttributes(); for (int i = 0; i <nnm.getLength(); i++) { Node node =nnm.item(i); String key =node.getLocalName(); String value =node.getNodeValue(); if(key.equals("entity")) { if(parserContext.getRegistry().containsBeanDefinition(value)) { beanDefinition.getPropertyValues().add(key,parserContext.getRegistry().getBeanDefinition(value)); } else { beanDefinition.getPropertyValues().add(key,new RuntimeBeanReference(value)); } } else { beanDefinition.getPropertyValues().add(key,value); } } return beanDefinition; } }


    这个类会在

    org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(Elementroot, BeanDefinitionParserDelegate delegate)这种方法中入口运行

    然后到org.springframework.beans.factory.xml.NamespaceHandlerSupport.parse(Elementelement, ParserContext parserContext);

    最后找到相应的BeanDefinitionParser运行parse方法。至于放入BeanDefinitionParser的入口就在自己定义的NamespaceHandler中init()方法中。

    com/ruishenh/spring/config/MyEntity.java实体类:

     

    package com.ruishenh.spring.config;
     
    import com.ruishenh.model.BaseModel;
     
    public classMyEntity extendsBaseModel{
     
        private int dbTypeID;
     
        private String dbTypeName;
     
        private String splitBy;
     
        private String sql;
     
        private String name;
     
        public String getName() {
            return name;
        }
     
        public void setName(String name) {
            this.name = name;
        }
     
        public String getSplitBy() {
            return splitBy;
        }
     
        public void setSplitBy(StringsplitBy) {
            this.splitBy = splitBy;
        }
     
        public String getSql() {
            return sql;
        }
     
        public void setSql(String sql) {
            this.sql = sql;
        }
     
        public int getDbTypeID() {
            return dbTypeID;
        }
     
        public void setDbTypeID(int dbTypeID) {
            this.dbTypeID = dbTypeID;
        }
     
        public String getDbTypeName(){
            return dbTypeName;
        }
     
        public void setDbTypeName(StringdbTypeName) {
            this.dbTypeName = dbTypeName;
        }
     
    }
     

    com/ruishenh/spring/config/MyExecutor.java实体类:

     

    package com.ruishenh.spring.config;
     
    import com.ruishenh.model.BaseModel;
     
    public classMyExecutor  extends BaseModel{
     
        private String name;
     
        private int delay;
     
        private int interval;
     
        private String address;
     
        private MyEntity entity;
     
        public MyEntity getEntity() {
            return entity;
        }
     
        public void setEntity(MyEntity entity) {
            this.entity = entity;
        }
     
        public int getDelay() {
            return delay;
        }
     
        public void setDelay(int delay) {
            this.delay = delay;
        }
     
        public int getInterval() {
            return interval;
        }
     
        public void setInterval(int interval) {
            this.interval = interval;
        }
     
        public String getAddress() {
            return address;
        }
     
        public void setAddress(Stringaddress) {
            this.address = address;
        }
     
       
        public String getName() {
            return name;
        }
     
        public void setName(String name) {
            this.name = name;
        }
     
    }

    測试类:

    package com.ruishenh.spring.test;
     
    import org.springframework.context.support.FileSystemXmlApplicationContext;
     
    import com.ruishenh.spring.config.MyEntity;
    import com.ruishenh.spring.config.MyExecutor;
     
    public classTest {
        public static void main(String[] args) {
            Stringconf = "classpath:spring/myTest.xml";
            FileSystemXmlApplicationContextac = newFileSystemXmlApplicationContext(conf);
            MyExecutorme = ac.getBean(MyExecutor.class);
            System.out.println(me.toString());
            MyEntity mye = ac.getBean(MyEntity.class);
            System.out.println(mye.toString());
        }
    }
     


    执行结果:

    MyExecutor[name=myexecutor,delay=2000,interval=5000,address=127.0.0.1,entity=MyEntity[dbTypeID=1,dbTypeName=mysql,splitBy=id,sql=1,name=mye]]

    MyEntity[dbTypeID=1,dbTypeName=mysql,splitBy=id,sql=1,name=mye]

    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    盒模型新增样式
    css3 文字处理
    popupWindow的用法(1)
    spinner适配器
    layer-list解决listView中相邻item之间线的重叠的问题
    安卓中常用的shape,selector,layer-list
    Pagerstwich tab样式加下拉刷新(三)
    PagerSwitch tab样式加下拉刷新(二)
    PagerSwitch tab样式加上下拉刷新(一)
    listview中textview响应部分文本点击事件
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/4635448.html
Copyright © 2011-2022 走看看