自己的自定义配置文件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]

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

最新文章

  1. iOS中NSLog输出格式大全
  2. Android—Bundle传递ArrayList&lt;T&gt;
  3. Ternary Search Trees 三分搜索树
  4. 蓝牙4.0 BLE基础之vdd检测new
  5. ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/var mysql 启动不了
  6. Java Hour 42 fastjson
  7. JiaThis WordPress分享插件安装全攻略
  8. smartUpload组件单文件下载
  9. TCP/IP详解学习笔记(10)-- DNS:域名系统
  10. 修改hosts文件解决OneDrive被墙的问题
  11. solrnet - document
  12. 别再说&ldquo;我已经努力了&rdquo;,你的&ldquo;努力&rdquo;一文不值!
  13. winform Label与DataGridView右对齐 分类: WinForm 2014-05-19 20:51 446人阅读 评论(0) 收藏
  14. 模拟Hibernate动态生成SQL语句
  15. 如何在ubuntu 12.04下搭建Python Django环境
  16. doubango(3)--协议栈的启动过程
  17. 升级 pip 超时解决方案
  18. [转] HTML5应用之文件上传
  19. (9)模板层 - templates(模板语言、语法、取值、过滤器、变量的使用)
  20. javascript 的原型与原型链的理解

热门文章

  1. 细节!重点!易错点!--面试java基础篇(一)
  2. Hadoop应用开发实战(flume应用开发、搜索引擎算法、Pipes、集群、PageRank算法)
  3. 基于visual Studio2013解决C语言竞赛题之1059最大平台
  4. Unity3D NGUI,uGUI总结
  5. 在JDBC中使用PreparedStatement代替Statement,同时预防SQL注入
  6. Servlet的学习(三)
  7. delpi中的RTTI初试
  8. 2013 CSU校队选拔赛(1) 部分题解
  9. 利用PHP SOAP扩展实现简单Web Services
  10. jquery中怎么删除&lt;ul&gt;中的整个&lt;li&gt;包括节点