Dubbo 对配置文件的解析

深入Dubbo源码 - Dubbo配置文件解析 本文代码:点这里 从16年开始接触Dubbo,刚开始觉得很神奇,配置非常简洁,与Spring配置无缝衔接。上网各种搜索,Zookeeper + Provider + Consumer,测试项目跑起来了,很开心。但是对于源码总是狠不下心学习,那么多类,那么多英文注释,吓退我了。最近终于狠下心来一点一点的Debug代码,终于有了点收货,记录下。 Dubbo配置文件Demo Provider配置文件... 阅读详情

注意:本文所述均为dubbox,因dubbo 好长时间没有维护了,dubbox的gitHub传送门

dubbox介绍

以下引用自官方介绍

Dubbox当前的主要功能
支持REST风格远程调用(HTTP + JSON/XML):基于非常成熟的JBoss RestEasy框架,在dubbo中实现了REST风格(HTTP + JSON/XML)的远程调用,以显著简化企业内部的跨语言交互,同时显著简化企业对外的Open API、无线API甚至AJAX服务端等等的开发。事实上,这个REST调用也使得Dubbo可以对当今特别流行的“微服务”架构提供基础性支持。 另外,REST调用也达到了比较高的性能,在基准测试下,HTTP + JSON与Dubbo 2.x默认的RPC协议(即TCP + Hessian2二进制序列化)之间只有1.5倍左右的差距,详见文档中的基准测试报告。
支持基于Kryo和FST的Java高效序列化实现:基于当今比较知名的Kryo和FST高性能序列化库,为Dubbo默认的RPC协议添加新的序列化实现,并优化调整了其序列化体系,比较显著的提高了Dubbo RPC的性能,详见文档中的基准测试报告。
支持基于Jackson的JSON序列化:基于业界应用最广泛的Jackson序列化库,为Dubbo默认的RPC协议添加新的JSON序列化实现。
支持基于嵌入式Tomcat的HTTP remoting体系:基于嵌入式tomcat实现dubbo的HTTP remoting体系(即dubbo-remoting-http),用以逐步取代Dubbo中旧版本的嵌入式Jetty,可以显著的提高REST等的远程调用性能,并将Servlet API的支持从2.5升级到3.1。(注:除了REST,dubbo中的WebServices、Hessian、HTTP Invoker等协议都基于这个HTTP remoting体系)。
升级Spring:将dubbo中Spring由2.x升级到目前最常用的3.x版本,减少版本冲突带来的麻烦。
升级ZooKeeper客户端:将dubbo中的zookeeper客户端升级到最新的版本,以修正老版本中包含的bug。
支持完全基于Java代码的Dubbo配置:基于Spring的Java Config,实现完全无XML的纯Java代码方式来配置dubbo
调整Demo应用:暂时将dubbo的demo应用调整并改写以主要演示REST功能、Dubbo协议的新序列化方式、基于Java代码的Spring配置等等。
修正了dubbo的bug 包括配置、序列化、管理界面等等的bug。

注:dubbox和dubbo 2.x是兼容的,没有改变dubbo的任何已有的功能和配置方式(除了升级了spring之类的版本)

常用的dubbo配置

一个常见的dubbo配置,参照我们项目中的配置

<!-- 提供方应用信息,用于计算依赖关系-->
    <dubbo:application name="XXXXX" organization="YYYY" owner="ZZZZ" logger="log4j"/>

    <dubbo:registry address="${dubbo.registry}" file="${dubbo.cache.file}" />
    <!--uncomment this if you want to test dubbo's monitor-->
    <!--  
    <dubbo:monitor protocol="registry"/>
    -->
    <!-- 定义dubbo协议-->
    <dubbo:protocol name="dubbo" port="${dubbo.port}" serialization="kryo"/>
    <!-- 定义rest协议 -->
    <dubbo:protocol name="rest" server="servlet" port="${dubbo.rest.port}" contextpath="${dubbo.rest.contextpath}"/>

    <!-- consumer的默认配置,不检查provider是否存在 -->
    <dubbo:consumer check="false" timeout="${dubbo.timeout}"/>
    <dubbo:provider timeout="${dubbo.timeout}" />
    <!-- 对外暴露的接口 -->
    <import resource="classpath:/config/server/spring-dubbo-provider.xml"/>

对外暴露的服务:

<dubbo:service
        interface="服务的接口类"
        ref="adDirectionalPackageServer" protocol="dubbo" />

服务消费者配置:

<dubbo:reference id="dubboExampleService"
        interface="服务的接口类"
        protocol="dubbo" />

以上是常见的dubbo配置方式,其配置与Spring结合堪称完美,几乎没有代码侵入,像使用本地代码一样简单,那么这种配置是如何读取的呢??
上文书《Spring源码阅读之-自定义配置的解析》说道,dubbo也是通过spring.handlers 配置文件声明的命名空间解析类,他负责的命名空间是谁呢?

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

可见其处理的是http://code.alibabatech.com/schema/dubbo 命名空间,并使用com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler类对其解析,其内部也是通过

 this.registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
        this.registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
        this.registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
        this.registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
        this.registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
        this.registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
        this.registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
        this.registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
        this.registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
        this.registerBeanDefinitionParser("annotation", new DubboBeanDefinitionParser(AnnotationBean.class, true));

这种方式对不同的元素,注册不同的解析器(其实是一个类),通过这段代码,发现上面配置中定义的元素,基本都有自己的解析器(DubboBeanDefinitionParser,这里dubbo把节点都通过该类来解析了)
这里先摘一个重点出来。

this.registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));

其对应构造器(dubbo源码上没有注释,不过看接下来的parse方法很好理解)

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

之前已经有文章说明了,其实针对自定义命名空间的bean解析会调用BeanDefinitionParser中的parse方法。DubboBeanDefinitionParser类中的parse方法会调用如下的parse方法。这里就很好理解了,因为创建beanDefinition对象,其设置的beanDefinition对象的beanClass为构造器第一个参数。结合起来即:dubbo将对应的节点内容,解析给对应的Class维护,下面可以总结配置节点和类实例的对应关系。

 @SuppressWarnings("unchecked")
    private static BeanDefinition parse(Element element, ParserContext parserContext, Class<?> beanClass, boolean required) {
        RootBeanDefinition beanDefinition = new RootBeanDefinition();
        beanDefinition.setBeanClass(beanClass);
        beanDefinition.setLazyInit(false);
        String id = element.getAttribute("id");
        if ((id == null || id.length() == 0) && required) {
            //***省略,生成Bean Id的过程**//
        }
        if (id != null && id.length() > 0) {
            if (parserContext.getRegistry().containsBeanDefinition(id))  {
                throw new IllegalStateException("Duplicate spring bean id " + id);
            }
            // 看这里,对beanDefinition的注册操作。
            parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);
            beanDefinition.getPropertyValues().addPropertyValue("id", id);
        }
        if (ProtocolConfig.class.equals(beanClass)) {
            //对应节点的处理,不关注
        } else if (ServiceBean.class.equals(beanClass)) {
            //对应节点的处理,不关注
        } else if (ProviderConfig.class.equals(beanClass)) {
            //该方法内部会调用parse方法,即每个service方法会重新调用这个parse
            parseNested(element, parserContext, ServiceBean.class, true, "service", "provider", id, beanDefinition);
        } else if (ConsumerConfig.class.equals(beanClass)) {
            parseNested(element, parserContext, ReferenceBean.class, false, "reference", "consumer", id, beanDefinition);
        }
        Set<String> props = new HashSet<String>();
        ManagedMap parameters = null;
        for (Method setter : beanClass.getMethods()) {
            String name = setter.getName();
            if (name.length() > 3 && name.startsWith("set")
                    && Modifier.isPublic(setter.getModifiers())
                    && setter.getParameterTypes().length == 1) {
                Class<?> type = setter.getParameterTypes()[0];
                String property = StringUtils.camelToSplitName(name.substring(3, 4).toLowerCase() + name.substring(4), "-");
                props.add(property);
                Method getter = null;
                try {
                    getter = beanClass.getMethod("get" + name.substring(3), new Class<?>[0]);
                } catch (NoSuchMethodException e) {
                    try {
                        getter = beanClass.getMethod("is" + name.substring(3), new Class<?>[0]);
                    } catch (NoSuchMethodException e2) {
                    }
                }
                if (getter == null 
                        || ! Modifier.isPublic(getter.getModifiers())
                        || ! type.equals(getter.getReturnType())) {
                    continue;
                }
                //***调用相关class的getter,setter方法,设置bean的属性值****//
                beanDefinition.getPropertyValues().addPropertyValue(property, reference);
            }
        }
        NamedNodeMap attributes = element.getAttributes();
        int len = attributes.getLength();
        for (int i = 0; i < len; i++) {
            Node node = attributes.item(i);
            String name = node.getLocalName();
            if (! props.contains(name)) {
                if (parameters == null) {
                    parameters = new ManagedMap();
                }
                String value = node.getNodeValue();
                parameters.put(name, new TypedStringValue(value, String.class));
            }
        }
        if (parameters != null) {
            beanDefinition.getPropertyValues().addPropertyValue("parameters", parameters);
        }
        return beanDefinition;
    }

对应配置节点与类对象的配置关系。

application->com.alibaba.dubbo.configcom.alibaba.dubbo.config.ApplicationConfig
module->com.alibaba.dubbo.config.ModuleConfig
registry->com.alibaba.dubbo.config.RegistryConfig
monitor->com.alibaba.dubbo.config.MonitorConfig
provider->com.alibaba.dubbo.config.ProviderConfig
consumer->com.alibaba.dubbo.config.ConsumerConfig
protocol->com.alibaba.dubbo.config.ProtocolConfig
service->com.alibaba.dubbo.config.ServiceBean
reference->com.alibaba.dubbo.config.ReferenceBean
annotation->com.alibaba.dubbo.config.AnnotationBean

类对象具体的属性值含义和节点配置方法,可参看一篇博文,

【可信数据空间-部署方案】 此部署架构体现了以下几个核心原则:去中心化: 数据存储和处理完全分布在各个参与者端,运营方只提供核心的协调和信任基础设施。安全边界清晰: 通过VPC、DMZ、防火墙、K8s命名空间等技术,在每个层级都建立了严格的安全边界。高可用与弹性: 所有关键服务均以集群方式部署,避免单点故障,并能根据负载动态伸缩。云原生: 全面采用容器化和Kubernetes编排,简化部署、管理和运维复杂度。合规性: 架构设计天然满足数据驻留要求(数据留在企业本地),并为所有操作提供不可篡改的审计追踪能力。 阅读详情

相关推荐

libcrypto.so.10(OPENSSL_1.0.2)(64bit) is needed by erlang-22.0.7-1.el7.x86_64

今天安装Rabbitmq的 erlang-22.0.7-1.el7.x86_64.rpmrpm包时遇到了这个坑,害找到说是不容易;错误信息在下面; [root@iz2zef7u84js1qeeq00ewwz RabbitMQ]# rpm -ivh erlang-22.0.7-1.el7.x86_64.rpm warning: erlang-22.0.7-1.el7.x86_64.rpm: Header V4 RSA/SHA1 Signature, key ID 6026dfca: NOKEY error:

qq_45782349的博客 5782

在 Dubbo 中使用 REST

什么是 REST REST 是 Roy Thomas Fielding[1]在 2000 年他的博士论文[2]“架构风格以及基于网络的软件架构设计” 中提出来的一个概念。REST 是REpresentationalStateTransfer 的缩写,翻译过来就是 “表现层状态转化”。REST 就是 Roy 在这篇论文中提出的面向互联网的软件所应当具备的架构风格。 按照 REpresentational State Transfer 的字面意思,可以把应用看成是一个虚拟的状态机,软件提供的不...

SlimApp 1767

反相器(inverter)和缓冲器(buffer)---附加与非门原理图

下面是对反相器(Inverter)和缓冲器(Buffer)从面积、驱动能力、时序等多个角度的详细对比,列出的是一般情况下的比较,具体情况可能会受到工艺节点、设计库和特定设计要求的影响。缓冲器(Buffer)是数字电路中常见的逻辑门之一,用于增强信号的驱动能力,而不改变信号的逻辑状态。如下图所示的CMOS反相器,由一个NMOS和PMOS组成,栅端gate相连作为输入端Vin,漏端相连作为输出端Vout,NMOS的源端接地,PMOS的源端接电源VDD.与反相器不同,缓冲器的输出与输入保持相同的逻辑状态。

hzmscut的博客 1万+

dubbox开发rest+json指南【转】

http://dangdangdotcom.github.io/dubbox/rest.html 目录 概述 REST的优点 应用场景 快速入门 标准Java REST API:JAX-RS简介 REST服务提供端详解 HTTP POST/GET的实现 Annotation放在接口类还是实现类 JSON、XML等多数据格式的支持 中文字符支持 XML数据格式的额外要...

weixin_33755847的博客 578

macOS 12.7.6部署Ollama+Dify避坑指南

本文介绍了在macOS 12.7.6系统下部署Ollama和Dify的详细步骤及避坑指南。主要内容包括:1)关闭系统完整性保护(SIP)以允许修改系统目录;2)安装特定版本的Docker(2.1.0.5)和docker-compose(v2.38.2)以避免兼容性问题;3)配置Ollama服务并下载nomic-embed-text和deepseek-r1:7b模型;4)针对macOS调整Dify的docker配置文件,包括延长超时时间、修改存储路径、增加资源限制等关键设置。文中提供了完整的命令操作步骤和配置

Hi20240217的博客 3101

030、微透镜阵列与光场成像:从光场相机到深度感知的演进

文章摘要: 光场成像通过微透镜阵列(MLA)同时记录光线的位置与方向,实现单次曝光获取三维信息。其核心架构包括主镜头+MLA+传感器或相机阵列,各有分辨率与体积的权衡。光场支持先拍照后对焦和深度估计,但受限于微透镜基线短,精度较低。深度算法需结合多视角立体匹配与极平面图像分析,并处理噪声和温度漂移等实际问题。光场适用于短距离动态场景(如手势识别),而远距离高精度需求仍需激光雷达。建议初学者通过二手光场相机和开源工具入门,理解光场“角度域”与“空间域”的协同机制。

sundong_81的博客 50

dubbo中间件的rest协议踩过的坑

一、所需jar包如下&lt;!-- dubbo开始 --&gt;           &lt;dependency&gt;             &lt;groupId&gt;com.alibaba&lt;/groupId&gt;             &lt;artifactId&gt;dubbo&lt;/artifactId&gt;             &lt;version&gt;2

java后端架构 2699

[QMT量化交易小白入门]-105、震荡市最适合的策略:ETF多标的动态网格策略,回测年化收益47.81%

本专栏主要是介绍QMT的基础用法,常见函数,写策略的方法,也会分享一些量化交易的思路,大概会写200篇左右。QMT的相关资料较少,在使用过程中不断的摸索,遇到了一些问题,记录下来和大家一起沟通,共同进步。

木头大左的博客 2062

dubbo ,dubbo-provider、dubbo-consumer 配置参数说明

dubbo-provider、dubbo-consumer 配置参数说明

愿我如星君如月 ... 夜夜流光相皎洁 ... 1万+

【我的Android进阶之旅】Android自定义View实现一个游戏摇杆,来实现监听遥动的方向或者监听摇动的角度的功能

一、需求描述 去年有个需求,需要使用自定义View实现一个游戏摇杆,来识别上下左右摇动的方向。 有点类似下面这样的王者荣耀游戏摇杆的效果 二、业界已有的参考资料 在下面这篇博客介绍了如何自定义游戏摇杆 2.1 博客介绍 Android自定义摇杆 2.1.1 功能 支持自适应大小 支持2个方向、4个方向、8个方向的摇动监听 支持摇动角度获取 可选回调模式 支持可摇动区域自定义 支持摇杆自定义 支持设置图片、色值、Shape图形 2.1.2 效果图 2.1.3 设置回调方式 setCallBac

字节卷动 1409

Unity的粒子系统使用shadergraph(内置管线)制作的一个顶点偏移shader,但是粒子模型移动时,顶点也会偏移?

🏆本文收录于 《全栈Bug调优(实战版)》 专栏,该专栏专注于分享我在真实项目开发中遇到的各类疑难Bug及其深层成因,并系统提供高效、可复现的解决思路和实操方案。无论你是刚入行的新手开发者,还是拥有多年项目经验的资深工程师,本专栏都将为你提供一条系统化、高质量的问题排查与优化路径,助力你加速成长,攻克技术壁垒,迈向技术价值最大化与职业发展的更高峰🚀!

**My Coding Family** 1174

Dubbo3 配置rest和dubbo两种协议发布应用服务

REST 是在 2000 年他的博士论文“架构风格以及基于网络的软件架构设计” 中提出来的一个概念。REST 是REStateTransfer 的缩写,翻译过来就是 “表现层状态转化”。REST 就是 Roy 在这篇论文中提出的面向互联网的软件所应当具备的架构风格。按照 REpresentational State Transfer 的字面意思,可以把应用看成是一个虚拟的状态机,软件提供的不是服务而是一系列的资源,对这些资源的访问通过统一的操作来访问,而返回的结果代表了资源状态的一次跃迁。

yimint的博客 3166

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Dubbo配置文件的解析

注: 以下内容解析会涉及到Spring容器的加载过程,所以需要对spring容器的启动过程有所了解。 1、spring容器在启动的时候会加载解析 resources 下的配置文件,同时会根据dubbo配置文件中的 http://dubbo.apache.org/schema/dubbo 找到 dubbo包下META-INF下的对应的DubboNameSpaceHandler.java 2、在加载...

Tiger的博客 470

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Dubbo配置文件解析

1,配置信息 先看看dubbo官方文档给出的初始化过程: 基于 dubbo.jar 内的 META-INF/spring.handlers 配置,Spring 在遇到 dubbo 名称空间时,会回调 DubboNamespaceHandler。 所有 dubbo 的标签,都统一用 DubboBeanDefinitionParser 进行解析,基于一对一属性映射,将 XML 标签解析为 Bean 对...

190

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

dubbo consumer读取配置文件无法解析问题

SpringMVC项目中同时有provider和consumer.其中地址为引用的配置文件属性。如下: basedata.properties属性文件 dubbo.registry.address:2181=zk.dev.xxx.com dubbo.registry.port=20880 dubbo.payload=16777216 dubbo.consumer.address:2181=zk.t...

u011494923的博客 4604

Dubbo配置文件解析和对象创建。

1.通过配置文件初始化。 dubbo的自定义命名空间,后续会通过这个命名空间来找到dubbo标签的解析方法,以及对象初始化。 由于具体的解析需要通过spring来做,转到spring,从DefaultNamespaceHandlerResolver中可以看到新命名空间的初始化代码,namespaceHandle.init()。 namespaceHandle对象可以在dubbo的配置...

IT从业者 363

Dubbo第一步:解析配置文件

项目启动时,先对xml的标签进行解析 在初始化前,将每一个解析器的内容都封装到相应的XXXConfig.class中 @Override public void init() { registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true))...

weixin_45220428的博客 245

Dubbo和Spring结合配置文件内容解析为bean的过程

本篇讲解一下Dubbo中Bean的加载过程以及简单介绍Dubbo中服务的暴露和服务的引用!Dubbo是结合Spring来进行使用的,其中bean依赖Spring的IOC容器进行管理。Spring默认的Bean加载机制肯定是不能去加载Dubbo提供的Bean,那么Dubbo中的Bean是如何加载到Spring 容器的呢?

阿飞云漫步 1万+

Dubbo学习记录(六)--Spring整合Dubbo中的Dubbo配置文件流程解析(二)

Java百战成仙

玄霄 3601

Dubbo学习记录(五)-Dubbo与Spring的配置文件解析流程原理分析

Java百战成仙

玄霄 1185

Dubbo配置指南:全面解析配置文件与核心配置项实战

Dubbo 的配置文件是服务治理、服务提供、服务消费等关键操作的基础,支持通过多种格式进行配置,包括 XML、YAML、Properties 文件以及通过编程 API 的方式。

木南曌的博客 1236

dubbo源码:配置文件加载自定义标签解析

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34064653的博客 172

dubbo解析-通过spring boot配置文件配置dubbo

dubbo使用spring boot配置文件配置的属性可以参见类DubboConfigConfiguration。 DubboConfigConfiguration有两个子类:Single和Multiple。 @EnableConfigurationBeanBindings({ @EnableConfigurationBeanBinding(prefix = "dubbo....

龚厂长的博客 979
上一篇: Spring 源码阅读 BeanFactory(三) 对象的初始化 singleton 草稿
下一篇: Spring中ApplicationContextAware使用说明
weiythi
博客等级 码龄16年 23粉丝 48原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值