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:alpha 和 custom: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
838

被折叠的 条评论
为什么被折叠?



