Spring 自定义标签的使用

工程目录:https://gitee.com/wuhan1/spring-parent/tree/master/spring-12
自定义标签有什么用?
       自定义标签可以说是spring为了给类似你我这样的开发人员扩展组件使用的,因为它提供了一个标准的公共可插拔的接口;目前我们都知道spring非常强大,不过实际上除了spring-core和spring-beans外,其他都是通过自定义标签扩展实现的,其次还有一些开源组件也是,如dubbo等。所以,对于想扩展spring组件的小伙伴来说,了解如何自定义标签和相应的原理是必须走的第一步。

如何自定义标签?
1、编写.schemas文件,通知spring容器我们定义的xsd文件在哪里;
2、编写.xsd文件,定义配置时可以使用的属性限制或者说支持的那些属性配置;
3、编写.handlers 文件,扩展NamespaceHandler命名空间注册器和定义及解析器;
4、在xml文件中使用自定义标签

详细例子说明,工程目录

1.定义bean属性,然后在xsd文件中声明

package com.xqc.redis;

public class RedisTag {
    private String id;
    private String ip;
    private Integer port;
    private String desc;

    public RedisTag(String ip, Integer port, String desc) {
        this.ip = ip;
        this.port = port;
        this.desc = desc;
    }
    public RedisTag() {
    }
    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public Integer getPort() {
        return port;
    }

    public void setPort(Integer port) {
        this.port = port;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public RedisTag(String ip, Integer port) {
        this.ip = ip;
        this.port = port;
    }

    public String getId() {
        return id;
    }

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

xsd文件

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://www.example.org/schema/xqc"
            xmlns="http://www.example.org/schema/xqc"
            elementFormDefault="qualified">
    <xsd:element name="redis">
        <xsd:complexType>
            <xsd:attribute name="id" type="xsd:string" />
            <xsd:attribute name="ip" type="xsd:string" />
            <xsd:attribute name="port" type="xsd:string" />
            <xsd:attribute name="desc" type="xsd:string" />
        </xsd:complexType>
    </xsd:element>

</xsd:schema>

2.通过spring.shemas指定xsd文件

http\://www.example.org/schema/xqc.xsd=META-INF/xqc.xsd

类似与key=value的形式,如果找不到会去网络上下载。

3.通过spring.handlers指定自定义标签的解析器入口

http\://www.example.org/schema/xqc=com.xqc.namespace.RedisNamespaceHandler

需要实现NamespaceHandler接口,我们继承的它的实现类NamespaceHandlerSupport

import com.xqc.parse.RedisBeanDefinitionParser;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;

public class RedisNamespaceHandler extends NamespaceHandlerSupport {

    public void init() {
        this.registerBeanDefinitionParser("redis",new RedisBeanDefinitionParser());
    }
}

在init方法里使用我们自定义的解析器,

4.自定义的解析器需要集成BeanDefinitionParser接口,本例中集成的是它的子接口AbstractSingleBeanDefinitionParser

package com.xqc.parse;

import com.xqc.redis.RedisTag;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;

public class RedisBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {

    @Override
    protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
        String ip = element.getAttribute("ip");
        String port = element.getAttribute("port");
        String desc = element.getAttribute("desc");
        builder.addPropertyValue("ip",ip);
        builder.addPropertyValue("port",Integer.parseInt(port));
        builder.addPropertyValue("desc",desc);
    }

    @Override
    protected Class<?> getBeanClass(Element element) {
        return RedisTag.class;
    }
}
v

按照上面的步骤,一个简单的自定义解析器就完成了,我们可以把工程打成jar包,然后在其他工程里配置使用,本例中我们就在自己当前的工程中解析使用
在applicationContext.xml中声明

<!--suppress SpringFacetInspection -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xqc="http://www.example.org/schema/xqc"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xsi:schemaLocation="
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
    http://www.example.org/schema/xqc http://www.example.org/schema/xqc.xsd">

    <xqc:redis id="redis"  ip="localhost" port="6379" desc="redis配置"></xqc:redis>

</beans>

通过容器获取配置

遇到的问题总结,按照我们上面的格式如果在bean和xsd中没有声明ID,这样使用

报错

翻译报错信息:





猜你喜欢

转载自blog.csdn.net/dhj199181/article/details/109039120