dubbo源码学习(二) : spring 自定义标签

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

1、编写实体类
2、编写Parser解析类
3、编写NameSpaceHandle类
4、配置spring.handlers
5、配置spring.schemas
6、配置customTag .xsd

标签实体类如下:

public class CustomTag {

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 CustomTagBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
        private final Class<?> beanClass;

        private final boolean required;

        public CustomTagBeanDefinitionParser (Class<?> beanClass, boolean required) {
                this.beanClass = beanClass;
                this.required = required;
        }

        protected Class getBeanClass(Element element) {
                return CustomTag.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 CustomTagNamespaceHandler extends NamespaceHandlerSupport {
        @Override
        public void init() {
                //实现init方法,解析CustomTag标签
                registerBeanDefinitionParser("customTag",new CustomTagBeanDefinitionParser(CustomTag.class,true));
        }
}

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

http\://www.51gitee.net/schema/customTag=springNameSpace.CustomTagNamespaceHandler

spring.schemas配置

http\://www.51gitee.net/schema/customTag/customTag.xsd=META-INF/customTag.xsd

customTag.xsd的配置

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema
                xmlns="http://www.51gitee.net/schema/customTag"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                xmlns:beans="http://www.springframework.org/schema/beans"
                targetNamespace="http://www.51gitee.net/schema/customTag"
                elementFormDefault="qualified"
                attributeFormDefault="unqualified">
        <xsd:import namespace="http://www.springframework.org/schema/beans" />
        <!-- 定义element名, customTagType对应了bean的属性  -->
        <xsd:element name="customTag" type="customTagType">
                <xsd:annotation>
                        <xsd:documentation><![CDATA[ The customTag config ]]></xsd:documentation>
                </xsd:annotation>
        </xsd:element>
        <!--  配置各属性值,有点像Mybatis配置对应的model   -->
        <xsd:complexType name="customTagType">
                <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 customTag name. ]]></xsd:documentation>
                        </xsd:annotation>
                </xsd:attribute>
                <xsd:attribute name="age" type="xsd:int">
                        <xsd:annotation>
                                <xsd:documentation><![CDATA[ The customTag age. ]]></xsd:documentation>
                        </xsd:annotation>
                </xsd:attribute>
                <xsd:attribute name="profession" type="xsd:string">
                        <xsd:annotation>
                                <xsd:documentation><![CDATA[ The customTag profession. ]]></xsd:documentation>
                        </xsd:annotation>
                </xsd:attribute>
                <xsd:attribute name="address" type="xsd:string">
                        <xsd:annotation>
                                <xsd:documentation><![CDATA[ The customTag address. ]]></xsd:documentation>
                        </xsd:annotation>
                </xsd:attribute>
                <xsd:attribute name="phone" type="xsd:string">
                        <xsd:annotation>
                                <xsd:documentation><![CDATA[ The customTag 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.51gitee.net/schema/customTag"
             xsi:schemaLocation="
         http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
         http://www.oschina.net/schema/customTag
         http://www.oschina.net/schema/customTag/customTag.xsd">

        <common:customTag 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");
                CustomTag customTag= (CustomTag) context.getBean("test");
                System.out.println(customTag.toString());
        }
}

输出结果:

  test
chewenliang
12
技术
bei jing
18618152379  

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

关注我可以获取it视频

原文地址:http://blog.51cto.com/13538361/2096231

时间: 2024-07-31 20:52:48

dubbo源码学习(二) : spring 自定义标签的相关文章

Dubbo源码学习(二)

@Adaptive注解 在上一篇ExtensionLoader的博客中记录了,有两种扩展点,一种是普通的扩展实现,另一种就是自适应的扩展点,即@Adaptive注解的实现类. @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) public @interface Adaptive { String[] value() default {}; } @Adapt

Dubbo源码学习--优雅停机原理及在SpringBoot中遇到的问题

相关文章: Dubbo源码学习文章目录 前言 主要是前一阵子换了工作,第一个任务就是解决目前团队在 Dubbo 停机时产生的问题,同时最近又看了一下 Dubbo 的源码,想重新写一下 Dubbo 相关的文章. 优雅停机原理 对于一个 java 应用,如果想在关闭应用时,执行一些释放资源的操作一般是通过注册一个 ShutDownHook ,当关闭应用时,不是调用 kill -9 命令来直接终止应用,而是通过调用 kill -15 命令来触发这个 ShutDownHook 进行停机前的释放资源操作.

dubbo源码学习(一)基础知识及使用的相关技术

初学dubbo的源码,只做尝试性的去学习,做为自己学习的一个记录,各位看官如果觉得写的有错误或理解的不对,请在留言区告诉我,互相学习.本人能力有限,有大神进入 时请指点. Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合),我们可以非常容易地通过Dubbo来构建分布式服务,并根据自己实际业务应用场景来选择合适的集群容错模式,这个对于很多应用都是迫切希望的,只需要通过简单的配置就能够实现分布式服务调用,也就

dubbo源码学习(四)初始化过程细节:解析服务

初学dubbo的源码,只做尝试性的去学习,做为自己学习的一个记录,各位看官如果觉得写的有错误或理解的不对,请在留言区告诉我,互相学习.本人能力有限,有大神进入 时请指点. 前面大概介绍了一下关于学习dubbo源码的一些基本知识,今天将真正去看dubbo内部的实现过程,看dubbo的源码前我先把dubbo的用户指南和开发指指南大概的看了一遍,然后从上面找到相应的切入点去看源码,今天将介绍的是dubbo的初始化解析bean的过程.从之前使用过dubbo一些经验,加上http://dubbo.io/的

dubbo源码学习一:基础知识及使用的相关技术

Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合),我们可以非常容易地通过Dubbo来构建分布式服务,并根据自己实际业务应用场景来选择合适的集群容错模式,这个对于很多应用都是迫切希望的,只需要通过简单的配置就能够实现分布式服务调用,也就是说服务提供方(Provider)发布的服务可以天然就是集群服务. Dubbo的产生背景.最初的需求.架构设计 等可以详细看官方的文档:http://dubbo.apach

Dubbo源码学习之-Adaptive自适应扩展

前言 最近三周基本处于9-10-6与9-10-7之间,忙碌的节奏机会丢失了自己.除了之前干施工的那段经历,只看参加软件开发以来,前段时间是最繁忙的了.忙的原因,不是要完成的工作量大,而是各种环境问题,各种沟通协调问题.从这个项目,我是体会到了人一多,花在沟通协调上的成本真的会不成比例的放大,制度好,再加上协调好,会极大的提高整体工作效率.怪不得当年华为跟IBM学完工作组织管理制度之后能爆发出如此强劲的战斗力.从另一个角度,也能发觉出为什么大公司招人都比较注重员工的个人实力与团队协作能力,因为如果

spring源码学习(1)——spring整体架构和设计理念

Spring是在Rod Johnson的<Expert One-On-One J2EE Development and Design >的基础上衍生而来的.主要目的是通过使用基本的javabean来完成以前只能用EJB完成的事情降低企业应用的复杂性.这一系列源码学习是基于Spring-4.3.11版本的. 一.Spring的整体架构 如图所示,spring可以被总结为一下几个部分: (1)Core Container 为Spring的核心容器,包含Beans,Core,Context和SpEL

dubbo源码学习(五)dubbo暴露服务的过程

初学dubbo的源码,只做尝试性的去学习,做为自己学习的一个记录,各位看官如果觉得写的有错误或理解的不对,请在留言区告诉我,互相学习.本人能力有限,有大神进入 时请指点. dubbo采用的nio异步的通信,通信协议默认为 netty,当然也可以选择 mina,grizzy.在服务端(provider)在启动时主要是开启netty监听,在zookeeper上注册服务节点,处理消费者请求,返回处理后的消息给消费者,消费者使用服务时主要是订阅服务的节点,监听zookeeper节点目录,服务端的变化时z

python 协程库gevent学习--gevent源码学习(二)

在进行gevent源码学习一分析之后,我还对两个比较核心的问题抱有疑问: 1. gevent.Greenlet.join()以及他的list版本joinall()的原理和使用. 2. 关于在使用monkey_patchall()之后隐式切换的问题. 下面我将继续通过分析源码及其行为来加以理解和掌握. 1. 关于gevent.Greenlet.join()(以下简称join)先来看一个例子: import gevent def xixihaha(msg): print(msg) gevent.sl