读懂Dubbo源码必备知识点之一

         最近新来的同事对Dubbo原理不太熟悉,特此写几篇文章,介绍如何分析Dubbo源码,要看懂Dubbo源码,还是要先弄懂几个知识点的,Spring的Schema自定义扩展功能就是其中要掌握的知识点之一;

当我们在阅读Dubbo User Guide时,在快速启动分栏中有这么一句话:
     Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载。
     这里就要先说一下Spring的Schema自定义扩展的功能了,了解Spring的人都会知道,Spring配置文件中有很多标定义如:<bean/>,我们在配置bean时,按照bean语法规则配置即可,spring就能解析这个元素,原理呢这里不在详述, 本文重介绍,在Dubbo中是如何应用Spring提供了的Schema扩展机制的,spring是如何识别<dubbo:service/>,<dubbo:protocol/>,<dubbo:provider/>,<dubbo:consumer/>等用户自定义的xml标签元素的.
     如果让Spring识别自动义xml标签,需要我们自己实现以下几步:
     自定义 xsd Schema 文件;
     编写一个我们自己的 bean;
     继承NamespaceHandlerSupport 重写init()方法,这块方法作用是spring容器载入入口;
     继承AbstractSingleBeanDefinitionParser类,重写getBeanClass,doParse方法, 这是解析XML元素的实现类;
     新建META-INF目录,创建spring.handlers,spring.schemas两个文件,这两个文件的作用就是让spring知道,怎么解析用户自定义的元素,用什么去解析这些元素;
     下面是实现的例子:
1.serviceconfig.xsd
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<xsd:schema xmlns="http://blog.csdn.net/tzqjz/schema/serviceconfig"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:beans="http://www.springframework.org/schema/beans"
            xmlns:tool="http://www.springframework.org/schema/tool"
            targetNamespace="http://blog.csdn.net/tzqjz/schema/serviceconfig"
            elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xsd:import namespace="http://www.springframework.org/schema/beans" />
    <xsd:import namespace="http://www.springframework.org/schema/tool" />

    <xsd:element name="serviceconfig">
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:extension base="beans:identifiedType">
                    <xsd:attribute name="ip" type="xsd:string">
                        <xsd:annotation>
                            <xsd:documentation>ip</xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                    <xsd:attribute name="port" type="xsd:string">
                        <xsd:annotation>
                            <xsd:documentation>端口</xsd:documentation>
                        </xsd:annotation>
                    </xsd:attribute>
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

</xsd:schema>


2.ServiceConfigNamespaceHandler

public class ServiceConfigNamespaceHandler extends NamespaceHandlerSupport {
    public void init() {
        registerBeanDefinitionParser("serviceconfig", new ServiceConfigBeanDefinitionParser());
    }
}

3.ServiceConfigBeanDefinitionParser

public class ServiceConfigBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
    @Override
    protected Class<?> getBeanClass(Element element) {
        return ServiceConfig.class;
    }
    @Override
    protected void doParse(Element element, BeanDefinitionBuilder bean) {
        String ip = element.getAttribute("ip");
        String port = element.getAttribute("port");
        bean.addPropertyValue("ip", ip);
        bean.addPropertyValue("port", port);
    }
}

4.ServiceConfig

public class ServiceConfig {
    private String ip;
    private String port;
    public String getIp() {
        return ip;
    }
    public void setIp(String ip) {
        this.ip = ip;
    }
    public String getPort() {
        return port;
    }
    public void setPort(String port) {
        this.port = port;
    }
}

5.spring.handlers

http\://blog.csdn.net/tzqjz/schema/serviceconfig=blog.csdn.net.spring.schema.ServiceConfigNamespaceHandler

6.spring.schemas

http\://blog.csdn.net/tzqjz/schema/serviceconfig/serviceconfig.xsd=META-INF/serviceconfig.xsd

7.applicationContext.xml

<?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:sc="http://blog.csdn.net/tzqjz/schema/serviceconfig"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
   http://blog.csdn.net/tzqjz/schema/serviceconfig
   http://blog.csdn.net/tzqjz/schema/serviceconfig/serviceconfig.xsd">
    <sc:serviceconfig id="test" ip="127.0.0.1" port="20880" />
</beans>

8.TestMain

public class TestMain {

    public static void main(String[] args) {
   
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
       ServiceConfig serviceConfig = (ServiceConfig) context.getBean("test");
        System.out.println(serviceConfig.getIp()+":"+serviceConfig.getPort());
    }

}

输出结果:
六月 02, 2017 1:07:58 上午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1a86f2f1: startup date [Fri Jun 02 01:07:58 GMT+08:00 2017]; root of context hierarchy
六月 02, 2017 1:07:59 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
127.0.0.1:20880

很简单吧.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值