Spring-based development-custom tags and their parsing

Posted by Blackwind on Thu, 11 Jul 2019 22:34:29 +0200

1. XML Schema

To customize tags, the first step is to write your own XML Schema. XML Schema's personal feelings are more complex, and online tutorials are relatively simple, so you can refer to spring-beans.xsd to draw on the gourd. Here is a brief introduction according to my own understanding.

1.1 The simplest label

A simplest label, in the form of:

<bf:head-routing key="1" value="1" to="test2"/>

This tag contains only a few attributes, which we define in the xsd file

<!-- Declare a label with the name head-routingļ¼ŒHis type is headRouting-->
<xsd:element name="head-routing" type="headRouting"></xsd:element>

    <!--  Definition head-routing Type, which is defined here as key,value,to,patten Four attributes -->
    <xsd:complexType name="headRouting">
        <xsd:attribute name="key" type="xsd:string" use="required"></xsd:attribute>
        <xsd:attribute name="value" type="xsd:string" use="required"></xsd:attribute>
        <xsd:attribute name="to" type="xsd:IDREF" use="required"></xsd:attribute>
        <xsd:attribute name="patten" type="xsd:string" default="string"></xsd:attribute>
    </xsd:complexType>

The type in the < xsd: attribute > tag is the format used to define the attribute, for example

  • xsd:string means a string with no formatting requirements
  • xsd:id denotes that the value of the attribute is an id with formatting requirements (for example, it cannot start with a number).
  • xsd:IDREF indicates that the value of the attribute corresponds to the value of an xsd:id attribute.
  • There are many others, such as number, double, datetime and so on.

1.2 Label of Complex Points

The so-called complexity is actually a nested label in the form of:

    &lt;bf:stop id="test1" ref="testNode"&gt;
        &lt;bf:head-routing key="1" value="1" to="test2"/&gt;
    &lt;/bf:stop&gt;

In fact, as long as you refer to the xsd of Spring's < bean > tag, you can define stop tag first.

    &lt;xsd:element name="stop"&gt;
        &lt;xsd:complexType&gt;
            &lt;xsd:complexContent&gt;
                &lt;xsd:extension base="beans:identifiedType"&gt;
                    &lt;xsd:group ref="stopElements"/&gt;
                    &lt;xsd:attributeGroup ref="stopAttributes"/&gt;
                &lt;/xsd:extension&gt;
            &lt;/xsd:complexContent&gt;
        &lt;/xsd:complexType&gt;
    &lt;/xsd:element&gt;

Among them,

  • <xsd: extension base= "beans: identifiedType"> defines the id attribute of the tag. Note that the type in spring-beans is referenced here.
  • Subtags allowed by <bf:stop> tags are defined in <xsd:group ref="stopElements"/>.
  • <xsd:attributeGroup ref="stopAttributes"/> defines the attributes allowed by the <bf:stop> tag
    &lt;xsd:group name="stopElements"&gt;
        &lt;xsd:sequence&gt;
            &lt;xsd:element ref="description" minOccurs="0"/&gt;
            &lt;xsd:choice minOccurs="0" maxOccurs="unbounded"&gt;
                &lt;xsd:element ref="head-routing"/&gt;
                  &lt;!-- More subtags continue to be added here, such as&lt;xsd:element ref="properties"/&gt; --&gt;
            &lt;/xsd:choice&gt;
        &lt;/xsd:sequence&gt;
    &lt;/xsd:group&gt;

    &lt;xsd:attributeGroup name="stopAttributes"&gt;
        &lt;xsd:attribute name="ref" type="xsd:IDREF" use="required"&gt;
            &lt;xsd:annotation&gt;                 
                &lt;xsd:appinfo&gt;
                      &lt;!-- This is used here. Spring tool xsd The label in,format checks--&gt;
                    &lt;tool:annotation kind="ref"&gt;
                        &lt;tool:expected-type type="com.lizo.node.Station"/&gt;
                    &lt;/tool:annotation&gt;
                &lt;/xsd:appinfo&gt;
            &lt;/xsd:annotation&gt;
        &lt;/xsd:attribute&gt;
        &lt;!-- More subtags continue to be added here, such as&lt;xsd:attribute name="value" type="xsd:string"/&gt; --&gt;

2. Configuration files

Once the xsd file has been written, it needs to be validated by configuring two files spring.handlers and spring.schemas in the resource/META-INF package of the project.

2.1 spring.schemas

The reconfiguration file is mainly a url to map the file we configure in the first step, in the form of the following

http\://www.lizo.com/schema/bf.xsd=META-INF/bf.xsd

In this way, you can add the url of spring.schemas to Spring's xml configuration file, omit the others, and add the following information to the < beans > tag

&lt;beans
        ..
       xmlns:bf="http://www.lizo.com/schema/bf"
       xsi:schemaLocation="
        ...
        http://www.lizo.com/schema/bf
        http://www.lizo.com/schema/bf.xsd
        "&gt;

After that, you can write your own tags in xml, for example, the namespace of the custom tag is bf.

   &lt;bf:stop id="test123" ref="testNode"&gt;
        &lt;bf:head-routing key="1" value="1" to="test1"/&gt;
        &lt;bf:head-routing key="3" value="4" to="test2"/&gt;
    &lt;/bf:stop&gt;

2.2 spring.handlers

This configuration file is used to configure and parse our bf tags, and then generate some BeanDefinition for registration. for example

http\://www.lizo.com/schema/bf=com.lizo.config.BusinessFlowNamespaceHandlerSupport

Business Flow Namespace Handler Supports are the tags we use to parse.

3. Custom Label Resolution

In the previous step, we configured the com.lizo.config.BusinessFlowNamespace Handler Support class as a class for parsing custom tags, so the namespace tags for bf are parsed using the tag parser registered here.

public class BusinessFlowNamespaceHandlerSupport extends NamespaceHandlerSupport {
    public void init() {
        //Register parsers for parsing & lt; bf: stop & gt; and
        registerBeanDefinitionParser("stop", new BusinessFlowBeanDefinitionParser());
    }
}

Our custom tag parser, Business FlowBean Definition Parser, implements the Bean Definition Parser interface

public interface BeanDefinitionParser {
    BeanDefinition parse(Element element, ParserContext parserContext);
}

Generally speaking, the basic process of registering bean s is:

  1. Resolution label
  2. Generate BeanDefinition from the analytic value.
  3. Registration label

Needless to say, parse tags, but focus on how to generate BeanDefinition

3.1 Generate BeanDefinition

A simplest BeanDefinition can be accomplished by setting Class and property injection. As follows:

RootBeanDefinition nodeWrapDefinition = new RootBeanDefinition();
//What class does the BeanDefinition correspond to?
nodeWrapDefinition.setBeanClass(StationRoutingWrap.class);
//name is the value obtained by parsing the tag
nodeWrapDefinition.getPropertyValues().addPropertyValue("name", name);

RuntimeBeanReference

RuntimeBeanReference is used to get BeanDefinition at runtime, because when we created the BeanDefinition, we only knew his beanName and were not sure whether it had been registered. RuntimeBeanReference, for example, is needed at this time.

RuntimeBeanReference refBean = new RuntimeBeanReference(ref);
        nodeWrapDefinition.getPropertyValues().addPropertyValue("station", refBean);

Collection class BeanDefinition

A BeanDefinition injects a List of attributes, at which point you need to use ManagedList (also known as ManagedMap,ManagedSet).

ManagedList routingConditions = new ManagedList();
....
nodeWrapDefinition.getPropertyValues().add("routing", routing);

3.2 Registered Beans

The function that registers the BeanDefinitionParser interface has a parameter, ParserContext, and a method called getRegistry(), so it's easy to register bean s.

parserContext.getRegistry().registerBeanDefinition("beanName",nodeWrapDefinition);

summary

With these three steps, you can define your own tags and inject related bean s into the Spring container. Let's make our frame more convenient to use (more B)

Topics: Attribute Spring xml