一、简介

Spring为基础Spring XML格式提供了基于schema的扩展机制,用于定义和配置bean。

创建新的XML配置可以通过以下步骤:

  • 编写描述自定义元素XML schema

  • 编写一个或多个BeanDefinitionParser实现代码

  • 编写自定义NamespaceHandler实现

  • 按照Spring的约定配置上述模块

二、实践

1、Java Bean

package custom;

public class CacheConfig {

	private String id;
	private int size;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public int getSize() {
		return size;
	}

	public void setSize(int size) {
		this.size = size;
	}

}

2、XML schema

XSD文件用于描述自定义标签的结构和约束,主要用来验证标签的合法性。

cache.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://mycompany.com/schema/cache"
            xmlns="http://mycompany.com/schema/cache">
    <xsd:element name="cache">
        <xsd:complexType>
            <xsd:attribute name="id"   type="xsd:string" use="required"/>
            <xsd:attribute name="size" type="xsd:int"    use="optional"/>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

需将此文件放在META-INF目录下。

3、BeanDefinitionParser

标签处理器负责解析XML中的属性设置到Bean中:

package custom;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;

public class CacheBeanDefinitionParser implements BeanDefinitionParser{

	@Override
	public BeanDefinition parse(Element element, ParserContext parserContext) {
		RootBeanDefinition beanDefinition = new RootBeanDefinition();
		beanDefinition.setBeanClass(CacheConfig.class);
		beanDefinition.setLazyInit(false);
		
		String id = element.getAttribute("id");
		beanDefinition.getPropertyValues().add("id", id);
		beanDefinition.getPropertyValues().add("size", element.getAttribute("size"));
		
		parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);
		return beanDefinition;
	}

}

4、NamespaceHandler

命名空间处理器将标签名与对应的解析器关联起来:

package custom;

import org.springframework.beans.factory.xml.NamespaceHandlerSupport;

public class CacheNamespaceHandler extends NamespaceHandlerSupport{

	@Override
	public void init() {
		registerBeanDefinitionParser("cache", new CacheBeanDefinitionParser());
	}

}

5、配置

在META-INF目录下新建spring.schemas文件,内容如下:

http\://mycompany.com/schema/cache.xsd=META-INF/cache.xsd

在META-INF目录下新建spring.handlers文件,内容如下:

http\://mycompany.com/schema/cache=custom.CacheNamespaceHandler

META-INF目录结构如下:

META-INF
   cache.xsd
   spring.handlers
   spring.schemas

6、测试

在resource目录下新建spring.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:custom="http://mycompany.com/schema/cache"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://mycompany.com/schema/cache
           http://mycompany.com/schema/cache.xsd">

    <custom:cache id="localCache" size="100"/>
    <custom:cache id="distributeCache" size="9999"/>
    
</beans>
  • 测试类
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring.xml");
CacheConfig localCache = (CacheConfig) context.getBean("localCache");
CacheConfig distributeCache = (CacheConfig) context.getBean("distributeCache");

System.out.println(localCache.getSize());
System.out.println(distributeCache.getSize());

输出:

100
9999
参考资料