dubbo源码解析-服务暴露与发现

一、概述

dubbo是一个简单易用的RPC框架,通过简单的提供者,消费者配置就能完成无感的网络调用。那么在dubbo中是如何将提供者的服务暴露出去,消费者又是如何获取到提供者相关信息的呢?

二、dubbo与spring的整合

在了解dubbo的服务注册和服务发现之前,我们首先需要掌握一个知识点:Spring中自定义Schema

三、Spring自定义Schema

Dubbo 现在的设计是完全无侵入,也就是使用者只依赖于配置契约。在 Dubbo 中,可以使用 XML 配置相关信息,也可以用来引入服务或者导出服务。

配置完成,启动工程,Spring 会读取配置文件,生成注入相关Bean。那 Dubbo 如何实现自定义 XML 被 Spring 加载读取呢 ?

从 Spring 2.0 开始,Spring 开始提供了一种基于 XML Schema 格式扩展机制,用于定义和配置 bean

入门案例

学习和使用Spring XML Schema 扩展机制并不难,需要下面几个步骤:

1、创建配置属性的JavaBean对象

2、创建Spring.xml文件

3、编写Spring.handlers文件配置所有部件

4、自定义处理器类,并实现NamespaceHandler接口

5、自定义解析器,实现BeanDefinitionParser接口(最关键的部分)

6、编写Spring.schemas文件配置所有部件

7、创建一个 XML Schema 文件,描述自定义的合法构建模块,也就是xsd文件

1、定义JavaBean对象,在spring中此对象会根据配置自动创建

复制代码
public class User {
    private String id;  
    private String name;  
    private Integer age;
    //省略getter setter方法
}

2、定义spring.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:context="http://www.springframework.org/schema/context" 
  xmlns:util="http://www.springframework.org/schema/util" 
  xmlns:task="http://www.springframework.org/schema/task" 
  xmlns:aop="http://www.springframework.org/schema/aop" 
  xmlns:tx="http://www.springframework.org/schema/tx"
  xmlns:itheima="http://www.itheima.com/schema/user"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
          http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
          http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
          http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
  http://www.itheima.com/schema/user http://www.itheima.com/schema/user.xsd">

      <itheima:user id="user" name="zhangsan" age="12"></itheima:user>

  </beans>

3、编写Spring.handlers文件配置所有部件

定义spring.handlers文件,根据Spring.xml的xsi:schemaLocation="http://www.itheima.com/schema/user" 与NamespaceHandler类的对应关系;必须放在classpath下的META-INF文件夹中

复制代码
http\://www.itheima.com/schema/user=com.itheima.schema.UserNamespaceHandler

4、自定义处理器类,并实现NamespaceHandler接口

自定义UserNamespaceHandler类

复制代码
package com.itheima.schema;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;

public class UserNamespaceHandler extends NamespaceHandlerSupport {
    public void init() {
        registerBeanDefinitionParser("user", new UserBeanDefinitionParser());
    }
}

5、自定义解析器,实现BeanDefinitionParser接口(最关键的部分)

BeanDefinitionParser是标签对应的解析器,Spring读取到对应标签时会使用该类进行解析;

复制代码
  public class UserBeanDefinitionParser extends
          AbstractSingleBeanDefinitionParser {

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

      protected void doParse(Element element, BeanDefinitionBuilder bean) {
          String name = element.getAttribute("name");
          String age = element.getAttribute("age");
          String id = element.getAttribute("id");
          if (StringUtils.hasText(id)) {
              bean.addPropertyValue("id", id);
          }
          if (StringUtils.hasText(name)) {
              bean.addPropertyValue("name", name);
          }
          if (StringUtils.hasText(age)) {
              bean.addPropertyValue("age", Integer.valueOf(age));
          }
      }
  }

6、编写Spring.schemas文件配置所有部件

定义spring.schemas文件,根据Spring.xml的xsi:schemaLocation="http://www.itheima.com/schema/user.xsd" 与 user.xsd文件对应关系;必须放在classpath下的META-INF文件夹中。

复制代码
  http\://www.itheima.com/schema/user.xsd=META-INF/user.xsd

7、创建一个 XML Schema 文件,描述自定义的合法构建模块,也就是xsd文件

在META-INF下定义user.xsd文件,使用xsd用于描述标签的规则

复制代码
    <?xml version="1.0" encoding="UTF-8"?>  
    <xsd:schema   
        xmlns="http://www.itheima.com/schema/user"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"   
        xmlns:beans="http://www.springframework.org/schema/beans"  
        targetNamespace="http://www.itheima.com/schema/user"
        elementFormDefault="qualified"   
        attributeFormDefault="unqualified">  
        <xsd:import namespace="http://www.springframework.org/schema/beans" />  
        <xsd:element name="user">
            <xsd:complexType>  
                <xsd:complexContent>  
                    <xsd:extension base="beans:identifiedType">  
                        <xsd:attribute name="name" type="xsd:string" />  
                        <xsd:attribute name="age" type="xsd:int" />  
                    </xsd:extension>  
                </xsd:complexContent>  
            </xsd:complexType>  
        </xsd:element>  
    </xsd:schema>