侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130562 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

分布式服务Dubbo从入门到"精通"之Schema实现

2023-11-01 星期三 / 0 评论 / 0 点赞 / 51 阅读 / 10626 字

了解更多技术文章请点击原文链接 前言 尽管使用了Dubbo许久,但其实对于其了解还是九牛一毛,上个月通读了Netty实战(粗略的了解),突然有了解读Dubbo源码的欲望,时不待我,那就赶紧开始吧。

了解更多技术文章请点击原文链接

 

前言

 

尽管使用了Dubbo许久,但其实对于其了解还是九牛一毛,上个月通读了Netty实战(粗略的了解),突然有了解读Dubbo源码的欲望,时不待我,那就赶紧开始吧。

熟悉Dubbo的朋友,可能都知道其采用全spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载。

当然,如果你不想使用Spring配置,而希望通过API的方式进行调用,Dubbo也是支持的,但是官方是不推荐的(原因你猜)。

 

今天,就跟大家聊一聊Dubbo是如何基于Schema实现的。

准备

具体实现,需要使用到一下几个配置或者是类:
spring.handlers:解析所使用的类
spring.schemas:自定义标签的路径
DubboNamespaceHandler.Java:处理器
DubboBeanDefinitionParser.java:解析器
xxxxConfig.java:JavaBean建模

实现

这里我们以dubbo:application做案例介绍

实体类ApplicationConfig.java

位于com.alibaba.dubbo.config包下,截取部分代码:

public class ApplicationConfig extends AbstractConfig {    private static final long serialVersionUID = 5508512956753757169L;    private String name;    private String version;    private String owner;    private String organization;    private String architecture;    private String environment;    private String compiler;    private String logger;    private List<RegistryConfig> registries;    private MonitorConfig monitor;    private Boolean isDefault;    public ApplicationConfig() {    }    public ApplicationConfig(String name) {        setName(name);    }

编写dubbo.xsd文件

位于META-INF下,截取部分代码:

<?xml version="1.0" encoding="UTF-8" standalone="no"?><xsd:schema xmlns="http://code.alibabatech.com/schema/dubbo"    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://code.alibabatech.com/schema/dubbo">    <xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>    <xsd:import namespace="http://www.springframework.org/schema/beans"/>    <xsd:import namespace="http://www.springframework.org/schema/tool"/>    <xsd:annotation>        <xsd:documentation><![CDATA[ Namespace support for the dubbo services provided by dubbo framework. ]]></xsd:documentation>    </xsd:annotation>    <xsd:complexType name="applicationType">        <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 application name. ]]></xsd:documentation>            </xsd:annotation>        </xsd:attribute>        <xsd:attribute name="version" type="xsd:string">            <xsd:annotation>                <xsd:documentation><![CDATA[ The application version. ]]></xsd:documentation>            </xsd:annotation>        </xsd:attribute>        <xsd:attribute name="owner" type="xsd:string">            <xsd:annotation>                <xsd:documentation><![CDATA[ The application owner name (email prefix). ]]></xsd:documentation>            </xsd:annotation>        </xsd:attribute>        <xsd:attribute name="organization" type="xsd:string">            <xsd:annotation>                <xsd:documentation><![CDATA[ The organization name. ]]></xsd:documentation>            </xsd:annotation>        </xsd:attribute>        <xsd:attribute name="architecture" type="xsd:string">            <xsd:annotation>                <xsd:documentation><![CDATA[ The architecture. ]]></xsd:documentation>            </xsd:annotation>        </xsd:attribute>        <xsd:attribute name="environment" type="xsd:string">            <xsd:annotation>                <xsd:documentation><![CDATA[ The application environment, eg: dev/test/run ]]></xsd:documentation>            </xsd:annotation>        </xsd:attribute>        <xsd:attribute name="compiler" type="xsd:string">            <xsd:annotation>                <xsd:documentation><![CDATA[ The java code compiler. ]]></xsd:documentation>            </xsd:annotation>        </xsd:attribute>        <xsd:attribute name="logger" type="xsd:string">            <xsd:annotation>                <xsd:documentation><![CDATA[ The application logger. ]]></xsd:documentation>            </xsd:annotation>        </xsd:attribute>        <xsd:attribute name="registry" type="xsd:string" use="optional">            <xsd:annotation>                <xsd:documentation><![CDATA[ The application registry. ]]></xsd:documentation>            </xsd:annotation>        </xsd:attribute>        <xsd:attribute name="monitor" type="xsd:string" use="optional">            <xsd:annotation>                <xsd:documentation><![CDATA[ The application monitor. ]]></xsd:documentation>            </xsd:annotation>        </xsd:attribute>        <xsd:attribute name="default" type="xsd:string" use="optional">            <xsd:annotation>                <xsd:documentation><![CDATA[ Is default. ]]></xsd:documentation>            </xsd:annotation>        </xsd:attribute>    </xsd:complexType>    <xsd:element name="annotation" type="annotationType">        <xsd:annotation>             <xsd:documentation><![CDATA[ The annotation config ]]></xsd:documentation>         </xsd:annotation>    </xsd:element></xsd:schema>

关于xsd:schema的各个属性具体含义就不作过多陈述,大家可以参见

http://www.w3school.com.cn/schema/schema_elements_ref.asp

DubboBeanDefinitionParser和DubboNamespaceHandler实现解析

DubboNamespaceHandler会根据schema和节点名找到某个DubboBeanDefinitionParser,然后由DubboBeanDefinitionParser完成具体的解析工作。因此需要分别继承NamespaceHandlerSupport和实现BeanDefinitionParser类。

两个类都位于com.alibaba.dubbo.config.spring.schema包下,以下是DubboNamespaceHandler部分代码:

public class DubboNamespaceHandler extends NamespaceHandlerSupport {    static {        Version.checkDuplicate(DubboNamespaceHandler.class);    }    public void init() {        registerBeanDefinitionParser("application",                new DubboBeanDefinitionParser(ApplicationConfig.class, true));        registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(                ModuleConfig.class, true));        registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(                RegistryConfig.class, true));        registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(                MonitorConfig.class, true));        registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(                ProviderConfig.class, true));        registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(                ConsumerConfig.class, true));        registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(                ProtocolConfig.class, true));        registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(                ServiceBean.class, true));        registerBeanDefinitionParser("reference",                new DubboBeanDefinitionParser(ReferenceBean.class, false));        registerBeanDefinitionParser("annotation",                new DubboBeanDefinitionParser(AnnotationBean.class, true));    }}

DubboBeanDefinitionParser由于太长了,大家自行查阅源码。

定制spring.handlers和spring.schemas

编码完毕之后,还需要做一些配置工作。我们必须告诉Spring我们准备使用自定义的标签元素,告诉Spring如何解析元素,否则Spring没那么聪明。这里需要2个配置文件,spring.handlers和spring.schemas(位于META-INF下即可),用于告诉Spring自定义标签的文档结构以及解析它的类。两个文件内容分别如下:

spring.handlers:

http/://code.alibabatech.com/schema/dubbo/dubbo.xsd=META-INF/dubbo.xsd

spring.schemas:

http/://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler

注意 /是转义,一定要加,不然会提示报错。

spring-context-dubbo.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:dubbo="http://code.alibabatech.com/schema/dubbo"    xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://code.alibabatech.com/schema/dubbo        http://code.alibabatech.com/schema/dubbo/dubbo.xsd        ">    <!-- 提供方应用信息,用于计算依赖关系  部分代码-->    <dubbo:application name="itstyle" /></beans>

 

 



了解更多技术文章请点击原文链接

广告 广告

评论区