Dubbo source code analysis: extend Spring XML elements based on Extensible XML authoring

Insert picture description here

step

  1. Write XML Schema file, define XML structure
  2. Custom NamespaceHandler implementation
  3. Customize BeanDefinitionParser to parse XML into BeanDefinition
  4. Register to the Spring container

Extend Spring XML elements

The project structure is as follows
Insert picture description here

Write XML Schema file

@Data
@ToString
public class User {
    
    

    private Long id;
    private String name;

}

users.xsd

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsd:schema xmlns="http://www.javashitang.com/schema/users"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://www.javashitang.com/schema/users">

    <xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>

    <!-- 定义 User 类型(复杂类型) -->
    <xsd:complexType name="User">
        <xsd:attribute name="id" type="xsd:long" use="required"/>
        <xsd:attribute name="name" type="xsd:string" use="required"/>
    </xsd:complexType>


    <!-- 定义 user 元素 -->
    <xsd:element name="user" type="User"/>
</xsd:schema>

Custom NamespaceHandler implementation

public class UsersNamespaceHandler extends NamespaceHandlerSupport {
    
    

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

Custom BeanDefinitionParser

public class UserBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
    
    

    @Override
    protected Class<?> getBeanClass(Element element) {
    
    
        return User.class;
    }

    @Override
    protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
    
    
        setPropertyValue("id", element, builder);
        setPropertyValue("name", element, builder);
    }

    private void setPropertyValue(String attributeName, Element element, BeanDefinitionBuilder builder) {
    
    
        String attributeValue = element.getAttribute(attributeName);
        if (StringUtils.hasText(attributeValue)) {
    
    
            builder.addPropertyValue(attributeName, attributeValue);

        }
    }
}

Register to the Spring container

spring.handlers

## 定义 namespace 与 NamespaceHandler 的映射
http\://www.javashitang.com/schema/users=com.javashitang.UsersNamespaceHandler

spring.schemas

http\://www.javashitang.com/schema/users.xsd=META-INF/users.xsd

test

users-context.xml

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

    <users:user id="1" name="小识"/>

</beans>
public class ExtensibleXmlAuthoringDemo {
    
    

    public static void main(String[] args) {
    
    
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/users-context.xml");
        context.refresh();
        // User(id=1, name=小识)
        System.out.println(context.getBean(User.class));
    }
}

Reference blog

[1]https://www.jianshu.com/p/8639e5e9fba6
[2]https://www.cnblogs.com/lifullmoon/p/14449414.html

Guess you like

Origin blog.csdn.net/zzti_erlie/article/details/114693044