当前位置: 首页 > news >正文

Dubbo源码解析(三)

一、Dubbo整合Spring启动流程

Dubbo的使用可以不依赖Spring,但是生产环境中Dubbo都是整合到Spring中一起使用,所以本章就解析Dubbo整合Spring的启动流程

一、传统的xml解析方式

一、Dubbo配置解析流程

在Java 中,一切皆对象。在JDK 中使用java.lang.Class 来描述类这个对象。而在Spring 中,bean 对象是操作核心。那么Spring 也需要一个东西来描述bean 这个对象,它就是BeanDefinition。

dubbo 的配置解析,不论是xml 方式的配置,还是注解的配置,目标都是把配置的属性值提取出来,变成dubbo 的组件bean(先由BeanDefinition 描述,然后委托spring 生成组件bean)。
下面以xml 的标签为例,列出每种配置对应要解析成为的目标组件bean。

首先,dubbo 自定义了spring 标签描述dubbo.xsd。在dubbo-config-spring模块下的src/main/resouce/META-INF 下,其次,在spring.handlers、spring.schemas 中指定解析类,将标签引入spring 中管理。

来到DubboNamespaceHandler中的init()方法,引入了很多DubboBeanDefinitionParser类,每个类会解析对应的配置,DubboBeanDefinitionParser 继承了spring 的BeanDefinitionParser 接口,spring 会调用parse 方法来读取每个标签配置,将属性值装入对应的BeanDefinition 定义中,后续spring会根据此BeanDefinition 定义生成dubbo 的组件bean。

继续看下DubboNamespaceHandler中的parse()方法,spring启动过程中同样会调用到这个方法,方法中有一行DubboSpringInitializer.initialize(parserContext.getRegistry())方法,就是向容器中加入一些基础bean。

我们先看两个比较重要的也就是ReferenceAnnotationBeanPostProcessor,DubboDeployApplicationListener;其中ReferenceAnnotationBeanPostProcessor是处理@Reference注解的,而DubboDeployApplicationListener是DubboDeployApplicationListener会监听Spring容器启动完成事件ContextRefreshedEvent,一旦接收到这个事件后,就会开始Dubbo的启动流程,就会执行DefaultModuleDeployer的start()进行服务导出与服务引入。

到此,那么dubbo中的一些必要的基本类已经假如到容器中了,也就是已经具备了解析处理dubbo.xml的基本条件。

二、Service标签处理

看下解析service标签的DubboBeanDefinitionParser,spring启动过程中会执行到parse方法,最终将service对应的Class信息设置到beanDefinition中,并且调用registerBeanDefinition方法将该beanDefinition注册到BeanDefinition中。

注意到此时的beanClass为ServiceBean,该类实现了InitializingBean接口,那么最终实例化的时候会调用afterPropertiesSet方法,这里会将ServiceBean加入到dubbo的configsCache缓存中,后面进行服务暴漏的时候就是从这个缓存中获取的。

三、Reference标签处理

同理reference标签的处理跟service标签一样,同样会通过DubboBeanDefinitionParser将他的class信息设置到beanDefinition中,此时class信息为referenceBean。这个接口实现了FactoryBean接口,那么最终spring会调用他的getObject方法,可以看到该方法里面去创建代理对象lazyProxy对象。

 referenceBean同时也实现了InitializingBean,最终也会调用到afterPropertiesSet()方法,这里会将referenceBean添加到缓存中。

四、DubboDeployApplicationListener

当Spring容器启动完成会发布事件ContextRefreshedEvent,DubboDeployApplicationListener会监听这个事件,一旦接收到这个事件后,就会开始Dubbo的启动流程,就会执行DefaultModuleDeployer的start()进行服务导出(服务暴漏)与服务引用。

还记得serviceBean初始化的时候执行的afterPropertiesSet方法吗,会将ServiceBean加入到dubbo的configsCache缓存中,这里会取出来挨个进行服务导出。

同时也会从configManager中获取references进行服务的引用,也就是生成具体的远程调用代理类,最终会调用到referenceConfig中的init方法,ref就是生成的代理对象,也就是实际的业务执行者。

二、注解方式

一、@EnableDubbo

服务端代码如下:需要在配置类上加上@EnableDubbo注解

@EnableDubbo注解上面有一个注解@DubboComponentScan,点进去这个注解发现他引入了这个DubboComponentScanRegistrar,该类实现了ImportBeanDefinitionRegistrar,spring启动过成功会调用registerBeanDefinitions方法

这里有三个比较关键的方法:

1、DubboSpringInitializer.initialize(registry);

这一步在xml解析的过程中已经解释过,引入了ReferenceAnnotationBeanPostProcessor,DubboDeployApplicationListener两个核心类;

2、Set<String> packagesToScan = getPackagesToScan(importingClassMetadata);

这一步是获取@DubboComponentScan上面的包路径,并传递给ServiceAnnotationPostProcessor,这个类会去扫描这个包下的带有@DubboService注解的类

3、将ServiceAnnotationPostProcessor注入到spring容器中,后续进行@DubboService注解解析

二、ServiceAnnotationPostProcessor

这个类实现了BeanDefinitionRegistryPostProcessor,最终Spring会调用到postProcessBeanDefinitionRegistry方法中,而scanServiceBeans方法就是将包路径下带有@DubboService的类解析为beanDefinition然后加入到spring容器中。

最终还是会通过serviceBean的afterPropertiesSet方法将ServiceBean加入到dubbo的configsCache缓存中,后面进行服务暴漏的时候就是从这个缓存中获取的

三、ReferenceAnnotationBeanPostProcessor

spring执行过程中会调用postProcessMergedBeanDefinition方法收集类中带有@DubboReference注解的属性,并最终调用postProcessPropertyValues将类上的属性注入到类中。

referenceBean也实现了InitializingBean,最终也会调用到afterPropertiesSet()方法,这里会将

referenceBean添加到缓存中。

四、DubboDeployApplicationListener

 当Spring容器启动完成会发布事件ContextRefreshedEvent,DubboDeployApplicationListener会监听这个事件,一旦接收到这个事件后,就会开始Dubbo的启动流程,就会执行DefaultModuleDeployer的start()进行服务导出(服务暴漏)与服务引入。

还记得serviceBean初始化的时候执行的afterPropertiesSet方法吗,会将ServiceBean加入到dubbo的configsCache缓存中,这里会取出来挨个进行服务导出。

在这里会从configManager中获取references进行服务的引用,也就是生成具体的远程调用代理类,最终会调用到referenceConfig中的init方法,ref就是生成的代理对象,也就是实际的业务执行者。

 三、服务调用

当进行服务调用的时候此时的demoService其实就是ReferenceBean.getObject()方法返回的lazyProxy对象,执行方法调用时会通过createObject然后getCallProxy获取到执行业务的对象。

最终会来到referenceConfig.get()方法,由于ref属性已经在dubbo启动的时候通过referServices初始化完成,所以这里已经不是null了,最终调用该ref执行业务逻辑的调用。

至此、Dubbo整合spring的大致启动流程结束,下个章节解析Dubbo的服务暴漏与注册。

相关文章:

Dubbo源码解析(三)

一、Dubbo整合Spring启动流程 Dubbo的使用可以不依赖Spring&#xff0c;但是生产环境中Dubbo都是整合到Spring中一起使用&#xff0c;所以本章就解析Dubbo整合Spring的启动流程 一、传统的xml解析方式 一、Dubbo配置解析流程 在Java 中&#xff0c;一切皆对象。在JDK 中使用…...

HarmonyOS Next星河版笔记--界面开发(5)

1.字符串 1.1.字符串拼接 作用&#xff1a;把两个或多个字符串&#xff0c;拼成一个字符串。&#xff08;通常是用来拼接字符串和变量&#xff09; hello world > helloworld 加好作用&#xff1a;拼接 let name:string 小明 console.log(简介信息,名字是 name) …...

Spring Boot3 实战案例合集上线了

Spring Boot3实战案例合集...

在Ubuntu 24.04 LTS上安装飞桨PaddleX

前面我们介绍了《在Windows用远程桌面访问Ubuntu 24.04.1 LTS》本文接着介绍安装飞桨PaddleX。 PaddleX 3.0 是基于飞桨框架构建的一站式全流程开发工具&#xff0c;它集成了众多开箱即用的预训练模型&#xff0c;可以实现模型从训练到推理的全流程开发&#xff0c;支持国内外多…...

Homebrew 命令大全

Homebrew 是 macOS 和 Linux 系统上的一个流行的包管理器&#xff0c;它可以帮助用户轻松地安装、更新和管理软件包。以下是一些常用的 Homebrew 命令&#xff1a; 安装 Homebrew 如果你还没有安装 Homebrew&#xff0c;可以使用以下命令在 macOS 上进行安装&#xff1a; /b…...

Docker+Django项目部署-从Linux+Windows实战

一、概述 1. 什么是Docker Docker 是一个开源的应用容器引擎&#xff0c;支持在win、mac、Linux系统上进行安装。可以帮助我们在一台电脑上创建出多个隔离的环境&#xff0c;比传统的虚拟机极大的节省资源 。 为什么要创建隔离的环境&#xff1f; 假设你先在有一个centos7.…...

前端 JS 实用操作总结

目录 1、重构解构 1、数组解构 2、对象解构 3、...展开 2、箭头函数 1、简写 2、this指向 3、没有arguments 4、普通函数this的指向 3、数组实用方法 1、map和filter 2、find 3、reduce 1、重构解构 1、数组解构 const arr ["唐僧", "孙悟空&quo…...

11.15 机器学习-集成学习方法-随机森林

# 机器学习中有一种大类叫**集成学习**&#xff08;Ensemble Learning&#xff09;&#xff0c;集成学习的基本思想就是将多个分类器组合&#xff0c;从而实现一个预测效果更好的集成分类器。集成算法可以说从一方面验证了中国的一句老话&#xff1a; # 三个臭皮匠&#xff0c…...

【SQL】E-R模型(实体-联系模型)

目录 一、介绍 1、实体集 定义和性质 属性 E-R图表示 2. 联系集 定义和性质 属性 E-R图表示 一、介绍 实体-联系数据模型&#xff08;E-R数据模型&#xff09;被开发来方便数据库的设计&#xff0c;它是通过允许定义代表数据库全局逻辑结构的企业模式&#xf…...

C/C++静态库引用过程中出现符号未定义的处理方式

问题背景&#xff1a; 在接入新库&#xff08;静态库&#xff09;时遇到了符号未定义问题&#xff0c;并发现改变静态库的链接顺序可以解决问题。 问题根源&#xff1a; 静态库是由 .o 文件拼接而成的&#xff0c;链接静态库时&#xff0c;链接器以 .o 文件为单位进行处理。链接…...

『VUE』27. 透传属性与inheritAttrs(详细图文注释)

目录 什么是透传属性&#xff08;Forwarding Attributes&#xff09;使用条件唯一根节点禁用透传属性继承总结 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 什么是透传属性&#xff08;Forwarding Attributes&#xff09; 在 V…...

借助Excel实现Word表格快速排序

实例需求&#xff1a;Word中的表格如下图所示&#xff0c;为了强化记忆&#xff0c;希望能够将表格内容随机排序&#xff0c;表格第一列仍然按照顺序编号&#xff0c;即编号不跟随表格行内容调整。 乱序之后的效果如下图所示&#xff08;每次运行代码的结果都不一定相同&#x…...

数据结构 ——— 层序遍历链式二叉树

目录 链式二叉树示意图​编辑 何为层序遍历 手搓一个链式二叉树 实现层序遍历链式二叉树 链式二叉树示意图 何为层序遍历 和前中后序遍历不同&#xff0c;前中后序遍历链式二叉树需要利用递归才能遍历 而层序遍历是非递归的形式&#xff0c;如上图&#xff1a;层序遍历的…...

使用 Prompt API 与您的对象聊天

tl;dr&#xff1a;GET、PUT、PROMPT。现在&#xff0c;可以使用新的 PromptObject API 仅使用自然语言对存储在 MinIO 上的对象进行总结、交谈和提问。在本文中&#xff0c;我们将探讨这个新 API 的一些用例以及代码示例。 赋予动机&#xff1a; 对象存储和 S3 API 的无处不在…...

SpringBoot整合Mybatis-Plus实践汇总

相关依赖 MyBatis-Plus涉及的依赖主要是Mybatis-start、和分页插件的依赖&#xff0c;不考虑使用额外分页插件的前提下&#xff0c;只需要mybatis-plus-boot-starter一个依赖即可与SpringBoot集成&#xff1a; <!--Mybatis-plugs--><dependency><groupId>co…...

基于Spring Boot的在线性格测试系统设计与实现(源码+定制+开发)智能性格测试与用户个性分析平台、在线心理测评系统的开发、性格测试与个性数据管理系统

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…...

Python实现人脸识别算法并封装为类库

引言 人脸识别技术在现代社会中应用广泛&#xff0c;从安全监控到智能门锁&#xff0c;再到社交媒体中的照片标记功能&#xff0c;都离不开这项技术。本文将详细介绍如何使用Python实现基本的人脸识别算法&#xff0c;并将其封装为一个类库&#xff0c;以便在多个项目中复用。…...

uniapp小程序分享使用canvas自定义绘制 vue3

使用混入结合canvas做小程序的分享 在混入里面定义一个全局共享的分享样式&#xff0c;在遇到特殊页面需要单独处理 utils/share.js import { ref } from vue; export default {onShow() {// 创建时设置统一页面的默认值uni.$mpShare {title: 分享的标题,path: /pages/home/…...

SpringCloud核心组件(四)

文章目录 NacosNacos 配置中心1.起源2.基本概念ProfileData IDGroup 3.基础配置a. bootstrap.ymlb. application.ymlc. nacos 中的配置 DataIDd.测试读取配置中心配置内容 4.配置隔离a.命名空间b.DataIDc.bootstrap.ymld.service 隔离 5.配置拆分a.配置拆分策略b.DataID 配置c.…...

如何把本地docker 镜像下载用到centos系统中呢?

如果需要将镜像下载到本地或在 CentOS 系统上使用该镜像&#xff0c;你可以按照以下步骤操作&#xff1a; 1. 拉取镜像 如果想将镜像从 Docker Hub 或其他镜像仓库下载到本地&#xff0c;可以使用 docker pull 命令。 如果使用的是本地构建的镜像&#xff08;如 isc:v1.0.0&…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

怎么让Comfyui导出的图像不包含工作流信息,

为了数据安全&#xff0c;让Comfyui导出的图像不包含工作流信息&#xff0c;导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo&#xff08;推荐&#xff09;​​ 在 save_images 方法中&#xff0c;​​删除或注释掉所有与 metadata …...

MySQL的pymysql操作

本章是MySQL的最后一章&#xff0c;MySQL到此完结&#xff0c;下一站Hadoop&#xff01;&#xff01;&#xff01; 这章很简单&#xff0c;完整代码在最后&#xff0c;详细讲解之前python课程里面也有&#xff0c;感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...

sshd代码修改banner

sshd服务连接之后会收到字符串&#xff1a; SSH-2.0-OpenSSH_9.5 容易被hacker识别此服务为sshd服务。 是否可以通过修改此banner达到让人无法识别此服务的目的呢&#xff1f; 不能。因为这是写的SSH的协议中的。 也就是协议规定了banner必须这么写。 SSH- 开头&#xff0c…...