dubbo源码分析5(dubbo服务暴露入口)

经过了前面这么多的铺垫,没错,前面说了这么一大堆的都是铺垫,我们说了spi,以及基于spring的扩展,这一篇就开始说说dubbo吧!

1.dubbo的配置文件解析

第一篇的时候,我们运行了 dubbo2.7.5(注意版本)的源码中的demo,我们可以看看服务提供者的配置文件,下面红色框框中应该不陌生了吧,嘿嘿( ̄▽ ̄)ノ

dubbo源码分析5(dubbo服务暴露入口)

然后我们上一篇中说的原理,去找到对应的命名空间处理器,下图所示;

所以我们就能知道命名空间处理器是DubboNamespaceHandler,而且我们还能看到一些有意思的东西,由于dubbo已经被阿里给贡献到开源社区apache了,所以这里还保留了之前ali的命名空间,我们也能继续使用,嘿嘿

自己有兴趣的话,可以自己看看下图中的spring.schemas文件以及对应的xsd文件了,看看这个xsd文件就能知道dubbo的每个标签都有些什么属性了(我表示没有这么大的兴趣๑乛◡乛๑,你们自己看,哈哈哈)

dubbo源码分析5(dubbo服务暴露入口)

继续看看这个DubboNamespaceHandler中,下图所示,我们随便看一秒钟就能知道dubbo的配置文件中,跟dubbo相关的标签就是这么14个,而且解析每个标签的解析起都是DubboBeanDefinitionParser去解析成BeanDefinition对象,只不过每个BeanDefinition里面封装的对象不一样罢了

dubbo源码分析5(dubbo服务暴露入口)

这么多标签我们说哪一个呢?先说说我最感兴趣的一个标签

dubbo源码分析5(dubbo服务暴露入口)

2.分布式服务基础

在说明

下图所示是我们看到的一个很经典的后端MVC三层结构, 这个应该都很熟悉了,而且这里后端的那三层都是在同一个机器上;

dubbo源码分析5(dubbo服务暴露入口)

那么问题来了,如果我要将service层放在另外一台机器上,你觉得Controller调用Service怎么做会比较好?下面有两种方式

方式一:我们在另外一台机器B上搭建一套MVC结构,注意,此时的机器B上的Controller中没有任何逻辑代码,就只是单纯的暴露一个机器B的入口,所以下面的步骤2可以直接使用Http请求去调用,比如使用Feign,HttpClient等http工具,聪明的人已经知道了,这特喵的就是springcloud的远程调用的方式嘛(╯-╰)/

dubbo源码分析5(dubbo服务暴露入口)

方式二,我们在机器B中,完全不需要Controller层,不就是两台机器通信么?大家知道java的网络编程吧,直接使用Socket建立网络通信就ok了;

我们现在使用dubbo就是用于实现下面的步骤2,更通俗的理解就是封装了java的网络编程(其实就是封装了netty框架),使得两台服务器之间可以进行远程调用,而不需要使用http请求的方式了;

dubbo源码分析5(dubbo服务暴露入口)

方式2优化: 但是由于我们的机器B可能有很多台,我们总不能在机器A中每次调用B机器的接口的时候,都要知道B的ip和端口吧?那多坑爹呀!

所以我们在机器B1和机器B2启动的时候,需要将机器B1和机器B2的接口信息(ip+端口+接口+方法+版本等信息)都放到注册中心(如下图的步骤1和步骤2),然后机器A从注册中心中将所有接口信息都给下载下(步骤3),然后决定去调用哪个机器上的服务(这里会涉及到负载均衡策略);

所以前端调用机器A,机器A根据调用的接口就可以找到对应接口所在的机器是B2(步骤5),然后通过网络编程去连接机器B2就好了

在这里机器A就是 服务消费者,机器B1和机器B2就是 服务提供者

dubbo源码分析5(dubbo服务暴露入口)

3.dubbo服务提供者暴露服务入口

在上面我们知道了,dubbo其实就是解决一台机器去远程调用另外一台机器的接口,而且还将服务暴露到注册中心里,并提供负载均衡策略 的远程调用框架;

那么在dubbo中什么叫做服务呀?我们看看服务提供者的配置文件,下图所示一个

业余小知识:可以思考一下,下图中这个接口只会暴露到注册中心中去么?(肯定是暴露到注册中心中一份,也会暴露一份到当前所在机器的jvm中呀!为什么呢?因为也有可能当前机器中其他的服务会使用到这个demoService服务呀,同一台机器上就不必走注册中心,肯定直接走jvm会更快呀)

所以我们又可以知道暴露服务,可以分为本地暴露和远程暴露嘛!当然,我们主要看的是远程暴露吧,哈哈哈哈๑乛◡乛๑

dubbo源码分析5(dubbo服务暴露入口)

下面我们就看看是怎么解析这个

3.1.DubboNamespaceHandler

这里就是缓存了dubbo每一个标签所对应的一个解析器,当实际去解析

这里,继续科普一下,在spring中的BeanDefinition的作用:对xml文件中每一个bean的一个统一的抽象,简单来说就是首先会将所有解析的bean都变成BeanDefinition

dubbo源码分析5(dubbo服务暴露入口)

3.2 DubboBeanDefinitionParser的parse方法

这个方法很长,我们只看解析ServiceBean的地方

在看这个方法之前, 继续强调一点,这里只是封装了BeanDefinition

dubbo源码分析5(dubbo服务暴露入口)

dubbo源码分析5(dubbo服务暴露入口)

看到这里,暂时不往后看了,后面一堆逻辑容易头晕,趁着头脑还很冷静, 我们看点清神醒脑的

3.3.实例化ServiceBean对象

在spring的后续初始化流程中,会对所有BeanDefinition中封装的实际的对象进行实例化,其中一个就是ServcieBean,我们看看ServiceBean是个什么东东( ̄o ̄) . z Z

这里请注意dubbo2.7.5之前和2.7.5之后的版本,变化很大很大,网上很多的ServcieBean的解析的博客都是2.7.5之前的,远古版本的了,我也在试着查了一些资料,尝试总结一下吧o(︶︿︶)o

3.3.1 先看看2.7.5之前

我把代码图和类的继承图都给出来,这里简单说一下spring中的原理,就不仔细看源码了
实现了InitializingBean和ApplicationListener接口的bean实例化的时候会做的事情,就是一个Bean首先在xml中进行配置,然后spring的容器在初始化的时候,会首先经过加载变成BeanDefinition对象,然后进行实例化BeanDefinition中实际的类型,这里实际的类型就是ServiceBean,在创建了一个ServiceBean对象之后,设置属性值,然后就是对ServiceBean进行初始化操作:会判断是否实现了InitializingBean接口,实现了的话,就会执行afterPropertiesSet方法先初始化一下,然后会判断ServcieBean有没有初始化方法,就是配置文件中

dubbo源码分析5(dubbo服务暴露入口)

dubbo源码分析5(dubbo服务暴露入口)

3.3.2 dubbo2.7.5的版本

我们看看代码和类图,很明显已经看不到那个EventListener接口了,那么我们就要看看这里是怎么暴露服务的

dubbo源码分析5(dubbo服务暴露入口)

dubbo源码分析5(dubbo服务暴露入口)

dubbo2.7.5提供了一个类DubboBootstrap类,这只是一个普通的监听器,但是里面有一个start方法,这里会调用exportServices()方法,然后就会去调用ServiceConfig的export()方法

(注意,serviceBean是ServiceConfig的一个子类),其实就可以看做会调用我们ServiceBean的export()方法,进行服务的暴露

dubbo源码分析5(dubbo服务暴露入口)

dubbo源码分析5(dubbo服务暴露入口)

那么我们再看看从哪里调用的这个DubboBootstrap的start()方法,那么我们就知道所有流程了,下面再贴几段代码

dubbo源码分析5(dubbo服务暴露入口)

dubbo源码分析5(dubbo服务暴露入口)

dubbo源码分析5(dubbo服务暴露入口)

dubbo源码分析5(dubbo服务暴露入口)

我们理一下思路,其实spring的初始化流程跟2.7.5之前是一样的,只不过在最后ioc和bean初始化完成之后,spring容器开始发布事件,在ioc容器中所有的实现了ApplicationListener接口的bean,首先会执行OneTimeExecutionApplicationContextEventListener的onApplicationEvent()方法,在这个方法里面再执行DubboBootstrapApplicationListener的onApplicationContextEvent()方法,在这方法里面会执行当前类的onContextRefreshedEvent()方法,最后就是执行dubboBootstrap.start();开始暴露服务

4.总结

这篇博客其实就是说了我们从哪个角度去切入到dubbo框架中,说的东西很少,但是非常非常重要,只有找到了切入点之后,我们才可以痛快的继续往后走,不然学了一下就忘了,特喵的,以后每次都要看一遍,多麻烦呀!

只要跟着我这里往后走,以后想看哪里点哪里,就不用百度了,哈哈哈哈

其实本篇要说的最重要的就是dubbo的2.7.5版本,与之前相比暴露服务的方式做了很大的改变,使用到了一个DubboBootstarp启动器,在spring容器初始化完成之后,会发布对应的事件然后会带着dubbo的启动器也会跑起来,从中我们也可以看出来spring的扩展性是真的厉害,dubbo也设计的非常巧妙,哈哈哈哈

下一篇真正的看看暴露服务的逻辑吧( ̄▽ ̄)ノ

Original: https://www.cnblogs.com/wyq1995/p/15679649.html
Author: java小新人
Title: dubbo源码分析5(dubbo服务暴露入口)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/574194/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Spring事务处理

    Spring的事务处理 Spring提供一种处理事务的统一模型 1、 事务 (1)事务是指一组sql语句的集合 (2)事务ACID原则:原子性、一致性、隔离性、持久性 2、 Spr…

    Java 2023年6月5日
    098
  • 阿里云一面:并发场景下的底层细节-伪共享问题

    最近看书看到的伪共享问题,直接触碰到知识盲区了,之前确实没听说过这个东西,打开百度就像吃饭一样自然。 虽然面经上出现的次数不多,不过我觉得还是很重要的一个问题,而且不难,花个五分钟…

    Java 2023年6月8日
    074
  • nginx 之 proxy_redirect详解【转】

    proxy_redirect 语法:proxy_redirect [ default|off|redirect replacement ] 默认值:proxy_redirect d…

    Java 2023年5月30日
    076
  • 【VUE】1.搭建一个webpack项目

    1.npm之类的安装跳过 2.安装npm install -g @vue/cli-init 初始化项目目录 vue init webpack vue_cutter_point_bl…

    Java 2023年6月5日
    074
  • 斐波那契数列(Fibonacci)递归和非递归实现

    序列前9项为:0, 1, 1, 2, 3, 5, 8, 13, 21 要注意非递归的话就是那一个变量帮助存储当前下一项的值,然后依次挪动两个指针往下即可 注意如果n太大 会溢出 O…

    Java 2023年5月30日
    0101
  • 深入源码理解SpringBean生命周期

    概述 本文描述下Spring的实例化、初始化、销毁,整个SpringBean生命周期,聊一聊BeanPostProcessor的回调时机、Aware方法的回调时机、初始化方法的回调…

    Java 2023年6月6日
    082
  • CountDownLatch在多线程统计另一个线程的动向

    CountDownLatch 在 CountDownLatch类里面有两个方法一个是await()字面意思是等待的一次,他和sleep()方法的区别就是sellp()会自己醒过来,…

    Java 2023年6月7日
    0138
  • RabbitMQ 发布订阅-实现延时重试队列

    RabbitMQ消息处理失败,我们会让失败消息进入重试队列等待执行,因为在重试队列距离真正执行还需要定义的时间间隔,因此,我们可以将重试队列设置成延时处理。今天参考网上其他人的实现…

    Java 2023年5月30日
    0103
  • Android学习笔记——基础入门

    Gradle gradle -b //应用名为java的插件,主要是为了引入JavaCompile、JavaExec两个任务 apply plugin: ‘java’ task c…

    Java 2023年6月8日
    0117
  • 【Unity Shader学习笔记】Unity光照-光照衰减

    Unity —共支持 4 种光源类型: 平行光 点光源(Point Light) 聚光灯(Spot Light) 面光源(area light) 面光源仅在烘焙时才可发挥作用, 因…

    Java 2023年6月9日
    084
  • 安装rabbitmq-server-3.8.9

    安装上Erlang客户端、rabbitmq-server-3.8.9,之后在目录C:\Program Files\RabbitMQ Server\rabbitmq_server-3…

    Java 2023年5月30日
    083
  • 爆肝30天,肝出来史上最透彻Spring原理和27道高频面试题总结

    在阅读面试题之前,小伙伴们可以先看看我之前发布的系列文章,Spring核心原理包括源码分析和用30个类手写。面试刷题固然很重要,但是知其然知其所以然更重要。 1 Spring环境预…

    Java 2023年6月7日
    063
  • Java学习-第一部分-第二阶段-第四节:常用类

    常用类 笔记目录:(https://www.cnblogs.com/wenjie2000/p/16378441.html) 包装类 包装类的分类 针对八种基本数据类型相应的引用类型…

    Java 2023年6月16日
    0101
  • @Import 源码解析

    转发请注明出处: @Import通过快速导入的方式实现把实例加入spring的IOC容器中;一般@EnableXXX注解是通过@Import实现具体的功能(@EnableXXX注解…

    Java 2023年6月8日
    059
  • spring-boot项目打包

    ps:https://start.spring.io/中导入Maven项目时,会默认选择一种打包方式(这里以jar包为例),导入Lombok插件和spring web。 1.打包成…

    Java 2023年6月13日
    071
  • Java8 stream 操作 GroupBy 设置键允许为null

    使用groupBy时,如果分组的 key 为 null,会抛出异常,可以写如下工具类规避这个问题: import java.util.ArrayList; import java….

    Java 2023年5月29日
    069
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球