自定义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());
    }
}

运行结果:

原文地址:https://www.cnblogs.com/heben/p/8000026.html