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文件:

 

 



    
        
            
            
            
            
            
            
            
            
            
            
        
    
    
        
            
                
                    
                
            
            
                
                    
                
            
            
                
                    
                
            
            
                
                    
                    
                    
                
                
                    
                        
                        
                        
                    
                
            
            
                
                    
                
                
                    
                        
                        
                        
                    
                
            
        
    

 

 

spring/myTest.xml文件:

 

 



 
    
    


 

 

 

 

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 

 

这个类会在

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)