自定义Spring标签
写了好几次了,结果一段时间之后就忘记了自己有写好的example,但是最后还是决定重新写一遍,把这个步骤记录下来
首先看整个项目结构
从transaction.xml开始,虽然图上报错了,实际上运行并没有问题,IDE功能的不完善吧。
其中声明了sb命名空间,并且schemaLocation中写明了schema地址是http://www.springbank.com/schema/springbank.xsd
<?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:sb="http://www.springbank.com/schema/springbank" 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.xsd http://www.springbank.com/schema/springbank http://www.springbank.com/schema/springbank.xsd "> <!-- 交易处理器扫描并实例化 --> <context:component-scan base-package="com.springbank.portal.controller"/> <sb:transaction id="testTransaction" action="testAction" template="noTemplate"></sb:transaction> </beans>
显然不会真的去http://www.springbank.com/schema/springbank.xsd寻找xsd,spring实际上是从spring.schemas文件里去寻找真正的地址,我这个example项目中,spring.schemas文件只有一行:
http\://www.springbank.com/schema/springbank.xsd=META-INF/schema/springbank.xsd
springbank.xsd的内容是
<?xml version="1.0" encoding="UTF-8"?> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.springbank.com/schema/springbank" xmlns:op="http://www.springbank.com/schema/springbank" elementFormDefault="qualified"> <element name="transaction"> <complexType> <attribute name="id" type="string" use="required"/> <attribute name="action" type="string" use="required"/> <attribute name="template" type="string" use="required"/> </complexType> </element> <element name="template" /> <element name="action"> <complexType> <attribute name="id" type="string" use="required"/> <attribute name="class" type="string" use="required"/> </complexType> </element> </schema>
schema的声明这个步骤就算完成了。接下来是要配置这个标签的解析类,这个配置在spring.handlers中完成:
http\://www.springbank.com/schema/springbank=com.demo.springtag.support.SpringbankNamespaceHandlerSupport
SpringbankNamespaceHandlerSupport类:
package com.demo.springtag.support; import org.springframework.beans.factory.xml.NamespaceHandlerSupport; public class SpringbankNamespaceHandlerSupport extends NamespaceHandlerSupport { @Override public void init() { registerBeanDefinitionParser("transaction", new TagTransactionBeanDefinitionParser()); } }
TagTransactionBeanDefinitionParser类
package com.demo.springtag.support; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; import org.springframework.util.StringUtils; import org.w3c.dom.Element; /** * @author wangxin * @contact 408657544@qq.com * @date Jul 11, 2017 * @Description:用于解析transaction标签 */ public class TagTransactionBeanDefinitionParser extends AbstractSingleBeanDefinitionParser { private final Logger log = LoggerFactory.getLogger(getClass()); @Override protected Class<?> getBeanClass(Element element) { return Transaction.class; } protected void doParse(Element element, BeanDefinitionBuilder bean) { String id = element.getAttribute("id"); String action = element.getAttribute("action"); String template = element.getAttribute("template"); if (StringUtils.hasText(id)) { bean.addPropertyValue("id", id); } if (StringUtils.hasText(action)) { bean.addPropertyValue("action", action); } if (StringUtils.hasText(template)) { bean.addPropertyValue("template", template); } } }
Transaction类
package com.demo.springtag.support; public class Transaction { private String id; private String template; private String action; public Transaction() { System.out.println("Bean Transaction have been created: "+toString()); } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getTemplate() { return template; } public String getAction() { return action; } public void setAction(String action) { this.action = action; } public void setTemplate(String template) { this.template = template; } @Override public String toString() { return "Transaction [id=" + id + ", template=" + template + "]"; } }
最后是测试类:
public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("classpath:transaction.xml"); Transaction transaction = (Transaction)context.getBean("testTransaction"); System.out.println(transaction.getTemplate()); } }
运行结果: