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]
版权声明:本文博客原创文章。博客,未经同意,不得转载。
spring 定义自己的标签 学习的更多相关文章
- Spring 4 官方文档学习(十二)View技术
		
关键词:view technology.template.template engine.markup.内容较多,按需查用即可. 介绍 Thymeleaf Groovy Markup Template ...
 - Spring 4 官方文档学习(十一)Web MVC 框架
		
介绍Spring Web MVC 框架 Spring Web MVC的特性 其他MVC实现的可插拔性 DispatcherServlet 在WebApplicationContext中的特殊的bean ...
 - Spring实战第六章学习笔记————渲染Web视图
		
Spring实战第六章学习笔记----渲染Web视图 理解视图解析 在之前所编写的控制器方法都没有直接产生浏览器所需的HTML.这些方法只是将一些数据传入到模型中然后再将模型传递给一个用来渲染的视图. ...
 - Spring入门IOC和AOP学习笔记
		
Spring入门IOC和AOP学习笔记 概述 Spring框架的核心有两个: Spring容器作为超级大工厂,负责管理.创建所有的Java对象,这些Java对象被称为Bean. Spring容器管理容 ...
 - Spring 4 官方文档学习(十一)Web MVC 框架之配置Spring MVC
		
内容列表: 启用MVC Java config 或 MVC XML namespace 修改已提供的配置 类型转换和格式化 校验 拦截器 内容协商 View Controllers View Reso ...
 - Spring.NET依赖注入框架学习--简单对象注入
		
Spring.NET依赖注入框架学习--简单对象注入 在前面的俩篇中讲解了依赖注入的概念以及Spring.NET框架的核心模块介绍,今天就要看看怎么来使用Spring.NET实现一个简单的对象注入 常 ...
 - Spring.NET依赖注入框架学习--简介
		
Spring.NET依赖注入框架学习--Spring.NET简介 概述 Spring.NET是一个应用程序框架,其目的是协助开发人员创建企业级的.NET应用程序.它提供了很多方面的功能,比如依赖注入. ...
 - Spring.NET依赖注入框架学习--入门
		
Spring.NET依赖注入框架学习--入门 在学些Spring.net框架之前,有必要先脑补一点知识,比如什么是依赖注入?IOC又是什么?控制反转又是什么意思?它们与Spring.net又有什么关系 ...
 - 6.1  如何在spring中自定义xml标签
		
dubbo自定义了很多xml标签,例如<dubbo:application>,那么这些自定义标签是怎么与spring结合起来的呢?我们先看一个简单的例子. 一 编写模型类 package ...
 
随机推荐
- 生成md5密码
			
mysql> select md5(concat((select md5("admin123") from test limit 1),'`xx')) from test; ...
 - WEB服务器、应用程序服务器区别
			
WEB服务器.应用程序服务器.HTTP服务器有何区别?IIS.Apache.Tomcat.Weblogic.WebSphere都各属于哪种服务器,这些问题困惑了很久,今天终于梳理清楚了: Web服务器 ...
 - mysql 结果集合切换
			
结果集A: 转换成为结果集B: mysql中实现例如以下: SELECT a.biz_date, CASE WHEN a.`event` = 'downClick' THEN a.uv END AS ...
 - linux中怎样设置dhcpd
			
linux中怎样设置DHCP 在 linux 以下设置 DHCP一点也不复杂﹐您全部要做的仅仅有一个文件﹕/etc/dhcpd.conf . 以下﹐我用我自己的设置文件来说说怎么改动这个文件﹕ d ...
 - Tomcat详细用法学习(五)
			
本篇接上一篇<Tomcat详细用法学习(四)>,主要讲解Tomcat服务器的管理平台 我们可能会将很多web应用交给Tomcat,那么Tomcat服务器就要对我们这些载入的web应用进行管 ...
 - c# 使用OracleParameter,同时使用replace函数
			
也算不上是手误吧,这个问题竟然困扰了我那么多天,就是更新代码的时候,使用replace,但是oracle在.net下竟然是不支持汉字,所谓使用类似update x set y='m' where y= ...
 - camel-name-utils 在驼峰风格跟下划线风格之间切换
			
用处 用来将字符串在驼峰风格跟下划线风格之间切换. 对于一般人可能没用.对于写orm框架的人有点作用. 样例: company_name -> companyName 安装方式 加入下面依赖到p ...
 - jQuery为啥要提供一个load()方法?
			
上午的时候,找个闲暇事件整理之前整理的一些关于jQuery的东西,看到了一个之前做的jQuery的$(document).ready()与window.onload()方法的比較. 上面两个方法最重要 ...
 - Ubuntu下is not in the sudoers file 问题解决
			
在Ubuntu12.04 下,使用sudo apt-get install XXX 时,突然跳出 username is not in the sudoers file的问题 然后我一查此userna ...
 - Cocos2d-x响应android返回键
			
开启按键按键监听 setKeypadEnabled(true); 重写监听事件函数 virtual void keyBackClicked(); 如: void BanQiuLayer::keyBac ...