Spring source extension point three: custom configuration file tags

The power of Spring is not only that it provides great convenience for Java developers, but also that its open architecture allows users to have the greatest ability to extend Spring.

When we use xml to define spring information, the default element only contains four of beans, bean, import, and alias. Any other tags are custom tags and need to introduce corresponding namespaces, such as context, aop tags, etc.

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
    
    
		if (delegate.isDefaultNamespace(root)) {
    
    
			NodeList nl = root.getChildNodes();
			for (int i = 0; i < nl.getLength(); i++) {
    
    
				Node node = nl.item(i);
				if (node instanceof Element) {
    
    
					Element ele = (Element) node;
					if (delegate.isDefaultNamespace(ele)) {
    
    
						//处理默认的标签元素
						parseDefaultElement(ele, delegate);
					}
					else {
    
    
						//处理自定义的标签元素
						delegate.parseCustomElement(ele);
					}
				}
			}
		}
		else {
    
    
			delegate.parseCustomElement(root);
		}
	}

The corresponding source code processing is in the parseBeanDefinitions method of the DefaultBeanDefinitionDocumentReader class.

Custom label elements

1. Define People.java

public class People {
    
    
    private String id;
    private int age;
    private String name;
    private String address;

    public People(String id, int age, String name, String address) {
    
    
        this.id = id;
        this.age = age;
        this.name = name;
        this.address = address;
    }

    public People() {
    
    
    }

    public String getId() {
    
    
        return id;
    }

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

    public int getAge() {
    
    
        return age;
    }

    public void setAge(int age) {
    
    
        this.age = age;
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public String getAddress() {
    
    
        return address;
    }

    public void setAddress(String address) {
    
    
        this.address = address;
    }

    @Override
    public String toString() {
    
    
        return "People{" +
                "id='" + id + '\'' +
                ", age=" + age +
                ", name='" + name + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}

2. Define people.xsd, spring.handlers and spring.schemas files in the resources/META-INF directory

people.xsd

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.bobo.com/schema/people"
        xmlns:tns="http://www.bobo.com/schema/people"
        elementFormDefault="qualified">
    <element name="people">
        <complexType>
            <attribute name ="id" type = "string"/>
            <attribute name ="age" type = "int"/>
            <attribute name ="name" type = "string"/>
            <attribute name ="address" type = "string"/>
        </complexType>
    </element>
</schema>

spring.handlers

http\://www.bobo.com/schema/people=com.bobo.custom.PeopleNamespaceHandler

spring.schemas

http\://www.bobo.com/schema/people.xsd=META-INF/people.xsd

3. Create the corresponding namespaceHandler class PeopleNamespaceHandler.java

package com.bobo.custom;

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

/**
 * @author bobo
 * @date 2020-10-20
 */

public class PeopleNamespaceHandler extends NamespaceHandlerSupport {
    
    
    @Override
    public void init() {
    
    
        super.registerBeanDefinitionParser("people",new PeopleBeanDefinitionParser());
    }
}

4. Create the corresponding BeanDefinitionParser class PeopleBeanDefinitionParser.java

package com.bobo.custom;

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

/**
 * @author bobo
 * @date 2020-10-20
 */

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

    @Override
    protected void doParse(Element element, BeanDefinitionBuilder builder) {
    
    
        String id = element.getAttribute("id");
        String age = element.getAttribute("age");
        String name = element.getAttribute("name");
        String address = element.getAttribute("address");
        if (StringUtils.hasLength(id)){
    
    
            builder.addPropertyValue("id",id);
        }
        if (StringUtils.hasLength(age)){
    
    
            builder.addPropertyValue("age",age);
        }
        if (StringUtils.hasLength(name)){
    
    
            builder.addPropertyValue("name",name);
        }
        if (StringUtils.hasLength(address)){
    
    
            builder.addPropertyValue("address",address);
        }
    }
}

5. Create the application-context.xml configuration file

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:bo="http://www.bobo.com/schema/people"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.bobo.com/schema/people http://www.bobo.com/schema/people.xsd">

    <bo:people id="bo" age="20" name="bobo" address="广东省深圳市"></bo:people>

</beans>

6. Create a test class

package com.bobo;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
    
    

    public static void main(String[] args) {
    
    
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application-context.xml");
        System.out.println(context.getBean("bo"));
    }
}

Run output

People{
    
    id='bo', age=20, name='bobo', address='广东省深圳市'}

Guess you like

Origin blog.csdn.net/u013277209/article/details/109186619