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 ...
随机推荐
- 基于visual Studio2013解决C语言竞赛题之1091多项式
题目 解决代码及点评 /************************************************************************/ /* ...
- MFC 关于对话框的注意点
1.对于模态对话框而言,单击确定以后对话框窗口对象即被销毁了,而对于非模态对话框来说,对话框的对象并未销毁而是隐藏起来(EndDialog函数),因此对于非模态对话框,必须重写OnOK这个虚函数,并在 ...
- MFC模板CArray及其派生类
CArray及其派生类 1. 简介:访问方法及效率和普通的数组一样,比普通数组强大的功能是可以改变数组的大小.Array采用队列方式存储数据,因而其内部数据元素是以物理方式顺序排列的,所以检索.顺序执 ...
- Android ListView 单条刷新方法实践及原理解析
对于使用listView配合adapter进行刷新的方法大家都不陌生,先刷新adapter里的数据,然后调用notifydatasetchange通知listView刷新界面. 方法虽然简单,但这里面 ...
- JS - 6款鼠标悬停效果
下载地址:http://www.lanrentuku.com/js/tupian-1093.html
- 也谈C#之Json,从Json字符串到类代码
原文:也谈C#之Json,从Json字符串到类代码 阅读目录 json转类对象 逆思考 从json字符串自动生成C#类 json转类对象 自从.net 4.0开始,微软提供了一整套的针对json进 ...
- uva 12300 - Smallest Regular Polygon
题意:给定两个点A和B,求包含这两个点的面积最小的正 n(已知)边形. #include<iostream> #include<iomanip> #include<cma ...
- spring获取bean 实例
ApplicationContext ctx = new ClassPathXmlApplication("applicationContext.xml"); DataSource ...
- Photon的使用
这几个月给公司一个正在做的半吊子游戏加pvp功能,一个人居然要2个多月弄个 PVP 类似 Dota 对战的游戏.我手里有套现成搭建服务端架构都没敢用起来,这服务器还是太初步了,只是验证了 Boost ...
- discuz!代码内置颜色大全(收藏)
加闪烁字:[light]文字[/light] 加文字特效:[shadow=255,red,2]文字[/shadow]: 在标签的中间插入文字可以实现文字阴影特效,shadow内属性依次为宽度.颜色和边 ...