Dubbo 源码学习(三)spring 自定义标签

我们在做dubbo的配置时很容易发现,dubbo有一套自己的标签,提供给开发者配置,其实每一个标签对应着一个 实体,在容器启动的时候,dubbo会对所有的配置进行解析然后将解析后的内容设置到实体里,最终dubbo会根据实体中的值生成贯穿全局的统一URL。利用自定义标签使配置简单明了化,与spring完美融合。

下面自己写一个自定义标签,主要需要如下 几个步骤:

1、编写实体类

2、编写Parser解析类

3、编写NameSpaceHandle类

4、配置spring.handlers

5、配置spring.schemas

6、配置chewl.xsd

实体类如下:

public class Chewl {  
  
    private String id;  
  
    private String name;  
  
    private Integer age;  
  
    private String profession;  
  
    private String address;  
  
    private String phone;  
  
    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 Integer getAge() {  
        return age;  
    }  
  
    public void setAge(Integer age) {  
        this.age = age;  
    }  
  
    public String getProfession() {  
        return profession;  
    }  
  
    public void setProfession(String profession) {  
        this.profession = profession;  
    }  
  
    public String getAddress() {  
        return address;  
    }  
  
    public void setAddress(String address) {  
        this.address = address;  
    }  
  
    public String getPhone() {  
        return phone;  
    }  
  
    public void setPhone(String phone) {  
        this.phone = phone;  
    }  
  
    public String toString(){  
        StringBuffer sb = new StringBuffer();  
        sb.append(id + "\n");  
        sb.append(name + "\n");  
        sb.append(age + "\n");  
        sb.append(profession + "\n");  
        sb.append(address + "\n");  
        sb.append(phone + "\n");  
        return sb.toString();  
    }  
}  

标签的解析类如下:

public class ChewlBeanDefinitionParserS extends AbstractSingleBeanDefinitionParser {  
    private final Class<?> beanClass;  
  
    private final boolean required;  
  
    public ChewlBeanDefinitionParserS(Class<?> beanClass, boolean required) {  
        this.beanClass = beanClass;  
        this.required = required;  
    }  
  
    protected Class getBeanClass(Element element) {  
        return Chewl.class;  
    }  
  
    protected void doParse(Element element, BeanDefinitionBuilder builder) {  
        //通过配置文件获取相应的值,设置到bean的属性中  
        String id = element.getAttribute("id");  
        String name = element.getAttribute("name");  
        String age = element.getAttribute("age");  
        String profession = element.getAttribute("profession");  
        String address = element.getAttribute("address");  
        String phone = element.getAttribute("phone");  
        if (StringUtils.hasText(id)) {  
            builder.addPropertyValue("id", id);  
        }  
        if (StringUtils.hasText(name)) {  
            builder.addPropertyValue("name", name);  
        }  
        if (StringUtils.hasText(age)) {  
            builder.addPropertyValue("age", age);  
        }  
        if (StringUtils.hasText(profession)) {  
            builder.addPropertyValue("profession", profession);  
        }  
        if (StringUtils.hasText(address)) {  
            builder.addPropertyValue("address", address);  
        }  
        if (StringUtils.hasText(phone)) {  
            builder.addPropertyValue("phone", phone);  
        }  
    }  
      
}

  NameSpaceHandle类如下:

public class ChewlNamespaceHandler extends NamespaceHandlerSupport {  
    @Override  
    public void init() {  
        //实现init方法,解析chewl标签  
        registerBeanDefinitionParser("chewl",new ChewlBeanDefinitionParserS(Chewl.class,true));  
    }  
}  

spring.handlers配置,前面那一串其实可以随便配置,只要一会和后面的配置一致即可

http\://www.oschina.net/schema/chewl=springNameSpace.ChewlNamespaceHandler  

spring.schemas配置

http\://www.oschina.net/schema/chewl/chewl.xsd=META-INF/chewl.xsd  

chewl.xsd的配置

<?xml version="1.0" encoding="UTF-8"?>  
<xsd:schema  
        xmlns="http://www.oschina.net/schema/chewl"  
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"  
        xmlns:beans="http://www.springframework.org/schema/beans"  
        targetNamespace="http://www.oschina.net/schema/chewl"  
        elementFormDefault="qualified"  
        attributeFormDefault="unqualified">  
    <xsd:import namespace="http://www.springframework.org/schema/beans" />  
    <!-- 定义element名,chewlType对应了bean的属性  -->  
    <xsd:element name="chewl" type="chewlType">  
        <xsd:annotation>  
            <xsd:documentation><![CDATA[ The chewl config ]]></xsd:documentation>  
        </xsd:annotation>  
    </xsd:element>  
    <!--  配置各属性值,有点像Mybatis配置对应的model   -->  
    <xsd:complexType name="chewlType">  
        <xsd:attribute name="id" type="xsd:ID">  
            <xsd:annotation>  
                <xsd:documentation><![CDATA[ The unique identifier for a bean. ]]></xsd:documentation>  
            </xsd:annotation>  
        </xsd:attribute>  
        <xsd:attribute name="name" type="xsd:string" use="required">  
            <xsd:annotation>  
                <xsd:documentation><![CDATA[ The chewl name. ]]></xsd:documentation>  
            </xsd:annotation>  
        </xsd:attribute>  
        <xsd:attribute name="age" type="xsd:int">  
            <xsd:annotation>  
                <xsd:documentation><![CDATA[ The chewl age. ]]></xsd:documentation>  
            </xsd:annotation>  
        </xsd:attribute>  
        <xsd:attribute name="profession" type="xsd:string">  
            <xsd:annotation>  
                <xsd:documentation><![CDATA[ The chewl profession. ]]></xsd:documentation>  
            </xsd:annotation>  
        </xsd:attribute>  
        <xsd:attribute name="address" type="xsd:string">  
            <xsd:annotation>  
                <xsd:documentation><![CDATA[ The chewl address. ]]></xsd:documentation>  
            </xsd:annotation>  
        </xsd:attribute>  
        <xsd:attribute name="phone" type="xsd:string">  
            <xsd:annotation>  
                <xsd:documentation><![CDATA[ The chewl phone. ]]></xsd:documentation>  
            </xsd:annotation>  
        </xsd:attribute>  
    </xsd:complexType>  
  
</xsd:schema>  

最后测试

在新建一个spring的配置文件如下

<?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:common="http://www.oschina.net/schema/chewl"  
       xsi:schemaLocation="  
     http://www.springframework.org/schema/beans  
     http://www.springframework.org/schema/beans/spring-beans-3.2.xsd  
     http://www.oschina.net/schema/chewl  
     http://www.oschina.net/schema/chewl/chewl.xsd">  
  
    <common:chewl id="test"  name="chewenliang" address="bei jing" age="12" phone="18618152379" profession="技术" />  
  
</beans>  

在java代码中测试

public class TestNameSpace {  
    public static void main(String[] args) {  
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-test.xml");  
        Chewl chewl = (Chewl) context.getBean("test");  
        System.out.println(chewl.toString());  
    }  
} 

 输出结果:

test  
chewenliang  
12  
技术  
bei jing  
18618152379  


spring的自定义标签自己很容易实现,具体要看在实际项目中如何正确的实用它,接下来会记录dubbo是如何解析、暴露服务。

猜你喜欢

转载自my.oschina.net/oosc/blog/1791737