Spring xml 自定义命名空间

1、定义要引入的 JavaBean 对象

此处定义一个命名空间下的 2 个对象,用来示例一个命名空间下可以包含多个对象

package org.example.customns;

public class Alpha {
    private String id;

    private String code;

    private Double price;

    public void show() {
        System.out.println("id = " + id + ", code = " + code + ", price = " + price);
    }

    public String getId() {
        return id;
    }

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

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }
}

package org.example.customns;

import java.time.LocalDateTime;

public class Beta {
    private String id;
    private String version;
    private LocalDateTime ts;

    public void describe() {
        System.out.println("id=" + id + ", version=" + version + ", ts=" + ts);
    }

    public String getId() {
        return id;
    }

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

    public String getVersion() {
        return version;
    }

    public void setVersion(String version) {
        this.version = version;
    }

    public LocalDateTime getTs() {
        return ts;
    }

    public void setTs(LocalDateTime ts) {
        this.ts = ts;
    }
}

2、创建约束文件 xsd,并定义每个对象的对应的 xml 标签约束

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns="http://org.example.com/schema/custom"
           targetNamespace="http://org.example.com/schema/custom">

    <xs:element name="alpha" >
        <xs:complexType>
            <xs:attribute name="id" type="xs:string" use="required"/>
            <xs:attribute name="code" type="xs:string" use="required"/>
            <xs:attribute name="price" type="xs:double" use="required"/>
        </xs:complexType>
    </xs:element>

    <xs:element name="beta" >
        <xs:complexType>
            <xs:attribute name="id" type="xs:string" use="required"/>
            <xs:attribute name="version" type="xs:string" use="required"/>
            <xs:attribute name="ts" type="xs:dateTime" use="required"/>
        </xs:complexType>
    </xs:element>

</xs:schema>

3、创建每个对象的 xml 标签解析器

自定义的 Bean 定义解析器继承自 AbstractSingleBeanDefinitionParser

  • 重写 getBeanClass 方法返回 bean 的类型
  • 重写 doParse 方法将文档元素 Element (即 xml 的标签)中的属性值注入到 BeanDefinitionBuilder 对象中用于创建 bean 对象
package org.example.customns;

import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.w3c.dom.Element;

public class AlphaBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
    @Override
    protected Class<?> getBeanClass(Element element) {
        return Alpha.class;
    }

    @Override
    protected void doParse(Element element, BeanDefinitionBuilder builder) {
        String id = element.getAttribute("id");
        String code = element.getAttribute("code");
        Double price = Double.valueOf(element.getAttribute("price"));
        builder.addPropertyValue("id", id);
        builder.addPropertyValue("code", code);
        builder.addPropertyValue("price", price);
    }
}
package org.example.customns;

import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.w3c.dom.Element;

import java.time.LocalDateTime;

public class BetaBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
    @Override
    protected Class<?> getBeanClass(Element element) {
        return Beta.class;
    }

    @Override
    protected void doParse(Element element, BeanDefinitionBuilder builder) {
        String id = element.getAttribute("id");
        String version = element.getAttribute("version");
        LocalDateTime ts = LocalDateTime.parse(element.getAttribute("ts"));
        builder.addPropertyValue("id", id);
        builder.addPropertyValue("version", version);
        builder.addPropertyValue("ts", ts);
    }
}

4、创建命名空间处理器,注册每个对象解析器

自定义的命名空间处理器继承自 NamespaceHandlerSupport

重写 init 方法,注册该命名空间下所有的自定义的 Bean 定义解析器

package org.example.customns;

import org.springframework.beans.factory.xml.NamespaceHandlerSupport;

public class CustomNamespaceHandler extends NamespaceHandlerSupport {
    @Override
    public void init() {
        registerBeanDefinitionParser("alpha", new AlphaBeanDefinitionParser());
        registerBeanDefinitionParser("beta", new BetaBeanDefinitionParser());
    }
}

5、创建命名空间的处理器和解析器的描述文件

需要在项目的 resource 目录下创建 META-INF 目录,并在其中创建两个文件:

  • spring.handlers:用于描述域名地址指向的自定义的命名空间处理器类(CustomNamespaceHandler)的全路径
  • spring.schemas:用于描述 xsd 文件的域名地址指向的 xsd 文件在项目中的真实地址(直接一个文件名就是指直接放在 resource 目录下)
http\://org.example.com/schema/custom=org.example.customns.CustomNamespaceHandler
http\://org.example.com/schema/custom/custom.xsd=custom.xsd

6、在 Spring 项目中使用自定义命名空间引入 Bean 对象

在 applicationContext.xml 文件中引入自定义的命名空间和标签

下面文件中的第 4 行、第 7 行、第 8 行就是引入的自定命名空间及其域名地址,在 xsi:schemaLocation 标签中,命名空间域名地址和 xsd 文件域名地址使成对出现的;

在 beans 标签内使用自定义的标签 custom:alphacustom:beta,注入需要的参数值

<?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:custom="http://org.example.com/schema/custom"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://org.example.com/schema/custom
        http://org.example.com/schema/custom/custom.xsd">

    <custom:alpha id="alpha" code="A001" price="299.1"/>

    <custom:beta id="beta" version="1.0" ts="2019-01-01T08:00:29"/>

</beans>

7、测试自定义的命名空间

package org.example.main;

import org.example.customns.Alpha;
import org.example.customns.Beta;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class NsXmlTest {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

        Alpha alpha = applicationContext.getBean(Alpha.class);
        alpha.show();

        Beta beta = applicationContext.getBean(Beta.class);
        beta.describe();

    }
}
2025-03-27 19:38:48,714 0      [           main] DEBUG ClassPathXmlApplicationContext  - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@7e0b37bc
2025-03-27 19:38:49,052 338    [           main] DEBUG ry.xml.XmlBeanDefinitionReader  - Loaded 2 bean definitions from class path resource [applicationContext.xml]
2025-03-27 19:38:49,115 401    [           main] DEBUG ort.DefaultListableBeanFactory  - Creating shared instance of singleton bean 'alpha'
2025-03-27 19:38:49,213 499    [           main] DEBUG ort.DefaultListableBeanFactory  - Creating shared instance of singleton bean 'beta'
id = alpha, code = A001, price = 299.1
id=beta, version=1.0, ts=2019-01-01T08:00:29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值