上一篇日志中我们已经实现了线程池的功能,使其具有了失败重试功能,这节课我们主要实现的功能就是自定义spring标签,达到以下的效果:
<qlt-utils:thread id="thread" retry="4" size="5"/>
这样看起来是不是比较明确而且简洁了。
要实现这个功能,我们要做下面几部工作:
1、编写schema文件,可参考http://www.w3school.com.cn/schema/index.asp,文件如下,该文件我存放的位置是,resource目录里的 /cn/qlt/common/utils/tag/qlt-utils.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://www.qlteacher.com/schema/qlt-utils"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:beans="http://www.springframework.org/schema/beans"
targetNamespace="http://www.qlteacher.com/schema/qlt-utils"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans"/>
<xsd:element name="thread">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="beans:identifiedType">
<!--线程池大小-->
<xsd:attribute name="size" use="optional">
<xsd:simpleType>
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="1"/><!--设置最小为1-->
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<!--重试次数-->
<xsd:attribute name="retry" use="optional" default="3">
<xsd:simpleType>
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="0"/><!--设置最小为0-->
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
</xsd:schema>
2、 定义handler,即定义的schema命名空间的handler,我们上面定义的文件的处理器,如下:
public class QltUtilsNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
//这里注册了某个元素的处理器,前面的名字即对应的schema文件中的某个element的名字
registerBeanDefinitionParser("thread", new QltThreadPoolBeanParser());
}
}
3、定义parser,即元素的解析,对某个element的解析,该类需按照以上方式进行注册
public class QltThreadPoolBeanParser extends AbstractSimpleBeanDefinitionParser {
/**
* 返回生成的bean的类型
*/
@Override
protected Class getBeanClass(Element element) {
return QltThreadPoolExecutor.class;
}
@Override
protected void doParse(Element element, BeanDefinitionBuilder builder) {
//这里就是对xml进行解析 并为我们的对象赋值。在spring中我们定义的各个bean,都存储为 BeanDefinition类型
String retry=element.getAttribute("retry");
builder.addPropertyValue("retry",retry);
String size=element.getAttribute("size");
if(!StringUtils.isEmpty(size)&&Integer.parseInt(size)>0){
builder.addPropertyValue("size",size);
}
}
}
4。配置schema文件的查找路径和NamespaceHandlerSupport 的查找路径。
在META-INF中新建spring.handlers和spring.schemas两个文件:
spring.handlers 内容:格式:schema的命名空间=该命名空间对应的NamespaceHandler
http\://www.qlteacher.com/schema/qlt-utils=cn.qlt.common.utils.tag.QltUtilsNamespaceHandler
spring.schemas 内容:格式:schema的名称=schema的具体路径
http\://www.qlteacher.com/schema/qlt/qlt-utils.xsd=/cn/qlt/common/utils/tag/qlt-utils.xsd
5、使用
在xml文件中要先导入我们定义的schema的命名空间,并且指定schema的位置,如下:
<?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:context="http://www.springframework.org/schema/context"
xmlns:qlt-utils="http://www.qlteacher.com/schema/qlt-utils"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.qlteacher.com/schema/qlt-utils http://www.qlteacher.com/schema/qlt/qlt-utils.xsd">
<!--上面要引入我们定义的schema-->
<context:component-scan base-package="cn.qlt"/>
<!--具体的使用-->
<qlt-utils:thread id="thread" retry="3" size="5"/>
</beans>
大功告成,是不是非常的简单啊,这里主要应用了spring自定义标签的知识,如想学习的同学可深入的去研究下