Spring源码深度解析(第2版)- 自定义标签的使用

目录

一、前言

1.简介

2.工具版本

二、项目目录结构

三、自定义标签的使用

1.创建一个POJO

2.定义一个XSD文件描述组件内容

3.创建一个类,继承AbstractSingleBeanDefinitionParser接口,用来解析XSD文件中的定义和组件定义。

4.建一个Handler文件,扩展自NamespaceHandlerSupport,目的是将组件注册到Spring容器。

5.编写Spring.handlers和Spring.schemas文件

6.创建测试配置文件,在配置文件中引入对应的命名空间以及XSD后,便可以直接使用自定义标签了。

7.测试


一、前言

1.简介

《Spring源码深度解析(第2版)》第4章默认标签的解析第1节自定义标签的使用,在学习解析之前需要先了解一下自定标签的使用过程。本文按照书中自定义标签的内容进行测试。

2.工具版本:

IntelliJ IDEA 2019.1.2

java version "1.8.0_77"

Spring version 5.2.0.BUILD-SNAPSHOT

二、项目目录结构

只需要看红色边框内的文件(在下载的源码中新增一个模块用来测试)

三、自定义标签的使用

        在很多情况下,我们需要为系统提供可配置化支持,简单的做法可以直接基于Spring的标准bean来配置,但配置较为复杂或者需要更多丰富控制的时候,会显得非常笨拙。一般的做法会用原生态的方式去解析定义好的XML文件,然后转化为配置对象。这种方式当然可以解决所有问题,但实现起来比较烦琐,特别是在配置非常复杂的时候,解析工作是一个不得不考虑的负担。Spring 提供了可扩展Schema的支持,这是一个不错的折中方案,扩展Spring自定义标签配置大致需要以下几个步骤(前提是要把Spring 的Core包加入项目中)。

  • 创建一个需要扩展的组件。
  • 定义一个XSD文件描述组件内容。
  • 创建一个文件,实现BeanDefinitionParser接口,用来解析XSD文件中的定义和组件
  • 定义。
  • 创建一个Handler文件,扩展自NamespaceHandlerSupport,目的是将组件注册到Spring
  • 容器。
  • 编写Spring.handlers和Spring.schemas文件。
  • 现在我们就按照上面的步骤带领读者一步步地体验自定义标签的过程。

1.创建一个POJO

User

package com.asyf.chapter04;

public class User {

	private String id;

	private String userName;

	private String email;

	public String getId() {
		return id;
	}

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

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	@Override
	public String toString() {
		return "User{" +
				"id='" + id + '\'' +
				", userName='" + userName + '\'' +
				", email='" + email + '\'' +
				'}';
	}
}

2.定义一个XSD文件描述组件内容

user.xsd

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
		targetNamespace="http://www.lexueba.com/schema/user"
		xmlns:tns="http://www.lexueba.com/schema/user"
		elementFormDefault="qualified">

	<element name="user">
		<complexType>
			<attribute name="id" type="string"/>
			<attribute name="userName" type="string"/>
			<attribute name="email" type="string"/>
		</complexType>
	</element>

</schema>

3.创建一个类,继承AbstractSingleBeanDefinitionParser接口,用来解析XSD文件中的定义和组件定义。

package com.asyf.chapter04;

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

public class UserBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {

	// Element对应的类
	protected Class getBeanClass(Element element) {
		return User.class;
	}

	// 从element中解析并提取对应的元素
	protected void doParse(Element element, BeanDefinitionBuilder beanDefinitionBuilder) {
		String id = element.getAttribute("id");
		String userName = element.getAttribute("userName");
		String email = element.getAttribute("email");
		// 将提取的数据放到BeanDefinitionBuilder中,待完成所有bean的解析后统一注册到BeanFactory中
		if (StringUtils.hasText("id")) {
			beanDefinitionBuilder.addPropertyValue("id", id);
		}
		if (StringUtils.hasText(userName)) {
			beanDefinitionBuilder.addPropertyValue("userName", userName);
		}
		if (StringUtils.hasText(email)) {
			beanDefinitionBuilder.addPropertyValue("email", email);
		}
	}

}

注意:书中写的是:创建一个文件,实现BeanDefinitionParser接口,用来解析XSD文件中的定义和组件定义。查看类图,AbstractSingleBeanDefinitionParser实现BeanDefinitionParser接口。

4.建一个Handler文件,扩展自NamespaceHandlerSupport,目的是将组件注册到Spring容器。

package com.asyf.chapter04;

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

public class MyNamespaceHandler extends NamespaceHandlerSupport {

	@Override
	public void init() {
		registerBeanDefinitionParser("user", new UserBeanDefinitionParser());
	}

}

5.编写Spring.handlers和Spring.schemas文件

默认位置是在工程的/META-INF/文件夹下,当然,你可以通过Spring 的扩展或者修改源码的方式改变路径。

  • spring.handlers

http\://www.lexueba.com/schema/user=com.asyf.chapter04.MyNamespaceHandler

  • spring.schemas

http\://www.lexueba.com/schema/user.xsd=META-INF/user.xsd

6.创建测试配置文件,在配置文件中引入对应的命名空间以及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:myname="http://www.lexueba.com/schema/user"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.lexueba.com/schema/user http://www.lexueba.com/schema/user.xsd">

    <myname:user id="testbean" userName="aaa" email="123456@qq.com"/>

</beans>

7.测试

package com.asyf.chapter04;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

public class MyTest {

	public static void main(String[] args) {
		BeanFactory bf = new XmlBeanFactory(new ClassPathResource("test.xml"));
		User user = (User) bf.getBean("testbean");
		System.out.println(user.toString());
	}

}

Console打印:

测试完毕。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值