spring 拾遗 0x00 如何在spring xml配置中使用自己的schema

如果我想在spring中使用下面一段自定义配置来实例化一个池

1
<donar:pool poolSize="50" name="mypool" id="mypool"/>

那么需要如下几步

Step 1 定义 xsd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:tool="http://www.springframework.org/schema/tool"
xmlns="http://code.raycloud.com/schema/donar"
targetNamespace="http://code.raycloud.com/schema/donar"> <!--这里是命名空间-->
<xsd:import namespace="http://www.springframework.org/schema/beans" />
<xsd:import namespace="http://www.springframework.org/schema/tool" />
<xsd:element name="pool">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="beans:identifiedType">
<xsd:attribute name="name" type="xsd:string">
<xsd:annotation>
<xsd:documentation>名称</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="poolSize" type="xsd:int">
<xsd:annotation>
<xsd:documentation>池大小</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
</xsd:schema>

Step 2 解析xml配置

  • 定义命名空间处理类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.donar.spring;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
/**
* Created by donar on 17/11/27.
* 命名空间处理类 继承NamespaceHandlerSupport 在init方法中注册 pool 元素的解析类
*/
public class DonarNameSpaceHandler extends NamespaceHandlerSupport{
@Override
public void init() {
registerBeanDefinitionParser("pool",new PoolBeanDefinitionParser());
}
}
  • 解析类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.donar.spring.bean;
/**
* Created by donar on 17/11/27.
*/
public class Pool {
Integer poolSize;
String name;
public Integer getPoolSize() {
return poolSize;
}
public void setPoolSize(Integer poolSize) {
this.poolSize = poolSize;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.donar.spring;
import com.donar.spring.bean.Pool;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.w3c.dom.Element;
/**
* Created by donar on 17/11/27.
*/
public class PoolBeanDefinitionParser extends AbstractSingleBeanDefinitionParser{
@Override
protected Class<?> getBeanClass(Element element) {
return Pool.class;
}
@Override
protected void doParse(Element element, BeanDefinitionBuilder builder) {
String name = element.getAttribute("name");
Integer size = Integer.valueOf(element.getAttribute("poolSize"));
builder.addPropertyValue("name",name);
builder.addPropertyValue("poolSize",size);
}
}

Step 3 添加spring资源文件

  • spring.handler 用来配置解析命名空间时对应的处理类
    http\://code.raycloud.com/schema/donar=com.donar.spring.DonarNameSpaceHandler
  • spring.schemas
    http\://code.raycloud.com/schema/donar/donar.xsd=META-INF/donar.xsd

完成这几步后我们在spring中配置中引用我们的xsd文件 就可以在spring加载bean的时候把我们自己命名空间的标签也纳入其中了

1
2
3
4
5
6
7
8
9
10
11
12
<?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:donar="http://code.raycloud.com/schema/donar"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://code.raycloud.com/schema/donar
http://code.raycloud.com/schema/donar/donar.xsd">
<donar:pool poolSize="50" name="mypool" id="mypool"/>
</beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import com.donar.spring.bean.Pool;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Created by donar on 17/11/27.
*/
public class TestSpringSchema {
@Test
public void test(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
Pool pool = (Pool) context.getBean("mypool");
System.out.println(pool.getName() + "---" + pool.getPoolSize());
}
}

输出结果

1
mypool---50