spring模仿dubbo自定义schema

半兽人 发表于: 2017-12-26   最后更新时间: 2017-12-28 17:15:32  
{{totalSubscript}} 订阅, 3,508 游览

dubbo里边很多如provider、consumer、registry的配置都是通过spring自定义Schema来实现的,为此,我们简单写一个Schema用例。

完成自定义一个shema名称为test,节点名为user的例子。

步骤

  1. 编写java bean
  2. 编写xsd配置文件
  3. 编写spring.handlersspring.schmas
  4. 编写applicationContext.xml
  5. 编写NamespaceHandler和BeanDefinitionParser

代码如下

1、 java bean

package com.system.schema.model;

public class User {
    private String id;
    private String name;
    private String sex;
    private int age;

    public String getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

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

2、 spring-schema/src/main/resources/META-INF/user.xsd 文件

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<xsd:schema xmlns="https://www.orchome.com/eric-lin/schema/user"
            xmlns:xsd="https://www.w3.org/2001/XMLSchema"
            xmlns:beans="https://www.springframework.org/schema/beans"
            xmlns:tool="https://www.springframework.org/schema/tool"
            targetNamespace="https://www.orchome.com/eric-lin/schema/user"
            elementFormDefault="qualified" attributeFormDefault="unqualified">

    <xsd:import namespace="https://www.springframework.org/schema/beans"/>
    <xsd:import namespace="https://www.springframework.org/schema/tool"/>

    <xsd:element name="user">
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:extension base="beans:identifiedType">
                    <xsd:attribute name="name" type="xsd:string">
                        <xsd:annotation>
                            <xsd:documentation>姓名</xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>

                    <xsd:attribute name="sex" type="xsd:string">
                        <xsd:annotation>
                            <xsd:documentation>性别</xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>

                    <xsd:attribute name="age" type="xsd:int">
                        <xsd:annotation>
                            <xsd:documentation>年龄</xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

3、 spring-schema/src/main/resources/META-INF/spring.handlers 文件内容

http\://www.orchome.com/eric-lin/schema/user=com.system.schema.UserNamespaceHandler

4、 spring-schema/src/main/resources/META-INF/spring.schemas文件内容

http\://www.orchome.com/eric-lin/schema/user/user.xsd=META-INF/user.xsd

5、 applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
       xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns:test="https://www.orchome.com/eric-lin/schema/user"
       xsi:schemaLocation="https://www.springframework.org/schema/beans
    https://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    https://www.orchome.com/eric-lin/schema/user
    https://www.orchome.com/eric-lin/schema/user/user.xsd">

    <test:user id="eric" name="123" sex="male" age="28" />
    <test:user id="eric2" name="1234" sex="man" age="29" />

</beans>

6、 NamespaceHandler

package com.system.schema;

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

public class UserNamespaceHandler extends NamespaceHandlerSupport {

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

7、 BeanDefinitionParser

package com.system.schema;

import com.system.schema.model.User;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.w3c.dom.Element;

public class UserBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {

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

    @Override
    protected void doParse(Element element, BeanDefinitionBuilder bean) {
        String id = element.getAttribute("id");
        String name = element.getAttribute("name");
        String sex = element.getAttribute("sex");
        int age = Integer.parseInt(element.getAttribute("age"));

        bean.addPropertyValue("id", id);
        bean.addPropertyValue("name", name);
        bean.addPropertyValue("sex", sex);
        bean.addPropertyValue("age", age);
    }
}

或另外一种方式

package com.system.schema;

import com.system.schema.model.User;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;

public class DubboBeanDefinitionParser implements BeanDefinitionParser {

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

    public BeanDefinition parse(Element element, ParserContext parserContext) {
        RootBeanDefinition beanDefinition = new RootBeanDefinition();
        beanDefinition.setBeanClass(User.class);
        beanDefinition.setLazyInit(false);

        String id = element.getAttribute("id");
        String name = element.getAttribute("name");
        String sex = element.getAttribute("sex");
        int age = Integer.parseInt(element.getAttribute("age"));

        beanDefinition.getPropertyValues().addPropertyValue("id", id);
        beanDefinition.getPropertyValues().addPropertyValue("name", name);
        beanDefinition.getPropertyValues().addPropertyValue("sex", sex);
        beanDefinition.getPropertyValues().addPropertyValue("age", age);
        parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);

        return beanDefinition;
    }
}

8、 测试

import com.system.schema.model.User;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestSpringSchema {

    @SuppressWarnings("resource")
    @Test
    public void test() {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");

        User user = (User) context.getBean("eric2");
        System.out.println(user.getId());
        System.out.println(user.getName());
        System.out.println(user.getSex());
        System.out.println(user.getAge());
    }
}

源码地址:https://github.com/orchome/spring-schema.git
maven项目,拉下来就能跑。

更新于 2017-12-28

查看shares更多相关的文章或提一个关于shares的问题,也可以与我们一起分享文章