Deep Analysis of Spring Source Code (2nd Edition)-Use of Custom Tags

table of Contents

I. Introduction

1 Introduction

2. Tool version

Second, the project directory structure

Third, the use of custom labels

1. Create a POJO

2. Define an XSD file to describe the content of the component

3. Create a class that inherits the AbstractSingleBeanDefinitionParser interface to parse the definitions and component definitions in the XSD file.

4. Create a Handler file, extended from NamespaceHandlerSupport, the purpose is to register the component to the Spring container.

5. Write Spring.handlers and Spring.schemas files

6. Create a test configuration file, and after introducing the corresponding namespace and XSD in the configuration file, you can directly use the custom label.

7. Test


I. Introduction

1 Introduction

"Spring Source Code Deep Analysis (Second Edition)" Chapter 4 Analysis of Default Labels Section 1 Use of Custom Labels, you need to understand the process of using custom labels before learning parsing. This article is tested according to the content of the custom label in the book.

2. Tool version:

IntelliJ IDEA 2019.1.2

java version "1.8.0_77"

Spring version 5.2.0.BUILD-SNAPSHOT

Second, the project directory structure

Just look at the file in the red frame (add a module to the downloaded source code for testing)

Third, the use of custom labels

        In many cases, we need to provide configurable support for the system. Simple methods can be configured directly based on Spring's standard beans, but when the configuration is more complicated or requires more rich control, it will be very clumsy. The general approach is to parse the defined XML file in the original ecological way, and then convert it into a configuration object. This method can certainly solve all problems, but it is more cumbersome to implement, especially when the configuration is very complicated, the analysis work is a burden that has to be considered. Spring provides support for extensible Schema, which is a good compromise. Extending Spring custom label configuration generally requires the following steps (provided that Spring's Core package is added to the project).

  • Create a component that needs to be extended.
  • Define an XSD file to describe the content of the component.
  • Create a file that implements the BeanDefinitionParser interface to parse the definitions and components in the XSD file
  • definition.
  • Create a Handler file, extended from NamespaceHandlerSupport, the purpose is to register the component to Spring
  • container.
  • Write Spring.handlers and Spring.schemas files.
  • Now we will follow the above steps to lead readers through the process of custom labeling step by step.

1. Create a 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. Define an XSD file to describe the content of the component

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. Create a class that inherits the AbstractSingleBeanDefinitionParser interface to parse the definitions and component definitions in the XSD file.

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);
		}
	}

}

Note: What is written in the book is: create a file to implement the BeanDefinitionParser interface to parse the definitions and component definitions in the XSD file. View the class diagram, AbstractSingleBeanDefinitionParser implements the BeanDefinitionParser interface.

4. Create a Handler file, extended from NamespaceHandlerSupport, the purpose is to register the component to the Spring container.

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. Write Spring.handlers and Spring.schemas files

The default location is under the /META-INF/ folder of the project. Of course, you can change the path by extending Spring or modifying the source code.

  • 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. Create a test configuration file, and after introducing the corresponding namespace and XSD in the configuration file, you can directly use the custom label.

<?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="[email protected]"/>

</beans>

7. Test

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 printing:

The test is complete.

Guess you like

Origin blog.csdn.net/cs373616511/article/details/107464844