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)

大家都在看

  • 性能优化,实践浅谈

    当经历了无数的日日夜夜,朝九晚九,攻克了无数难关,终于将系统预定功能开发完成,通过测试,部署上线后。你是否会感觉志得意满,到达了人生巅峰,高唱无敌是多么寂寞。 现实情况是,如果你这…

    Java 2023年6月15日
    061
  • 索引二倒排索引和正排索引

    一 以有限对无限 这个世界很多东西是无限的,比如可以创造无限的小说,可以创造无限个程序。但是小说虽然无限,小说中的字数却是有限,拿汉字来说,我查到的最高记录也就9万多个,常用的就五…

    Java 2023年5月30日
    084
  • JavaWeb_(视频网站)_五、视频模块1 视频上传

    视频模块 保存视频流程图 提交博客页面 submit-post-blog.html 提交视频页面 submit-post-video.html 在上传视频请求@RequestMap…

    Java 2023年5月29日
    055
  • WordPress网站中添加百度统计代码

    百度统计是流量分析平台,帮助收集网站访问数据,提供流量趋势、来源分析、转化跟踪、页面热力图、访问流等多种统计分析服务,同时与百度搜索、百度推广、云服务无缝结合,为网站的精细化运营决…

    Java 2023年6月8日
    078
  • Mybatis系列全解(八):Mybatis的9大动态SQL标签你知道几个?提前致女神!

    封面:洛小汐作者:潘潘 2021年,仰望天空,脚踏实地。 这算是春节后首篇 Mybatis 文了~跨了个年感觉写了有半个世纪 … 借着女神节 ヾ(◍°∇°◍)ノ゙提前祝…

    Java 2023年6月13日
    064
  • java基础4.20

    1.是否可以从一个static方法内部发出对非static方法的调用?不可以。因为非static方法是要与对象关联在一起的,必须创建一个对象后,才可以在该对象上进行方法调用,而st…

    Java 2023年6月5日
    041
  • SpringBoot+Mybatis配置多数据源,分包方式

    看了不少网上关于多数据源的配置,大致可分为两类,分包方式和通过切面方式; 第一个子项目ds01即时使用分包方式完成多数据源配置。 总结项目中出现的问题和解决办法: 数据库的连接信息…

    Java 2023年6月8日
    099
  • MySQL高性能学习笔记

    索引 何为索引?有什么作用? 索引是一种用于快速查询和检索数据的数据结构。常见的索引结构有: B 树, B+树和 Hash。索引的作用就相当于目录的作用。打个比方: 我们在查字典的…

    Java 2023年6月7日
    054
  • 【每天学一点-03】 使用Html5+Less实现简单的静态登录界面(入门Less)

    1、首先引用Less 有npm安装、cdn引用、或者下载Less.js本地引用,我采用的是第三种方法 less.js引用: 下载地址:https://github.com/less…

    Java 2023年6月5日
    077
  • SpringMVC执行流程

    SpringMVC三大核心组件 HandlerMapping处理器映射器:建立地址与方法的映射。 HandlerMapping负责根据用户请求url找到Handler即处理器,sp…

    Java 2023年5月30日
    069
  • Java并发之ReentrantLock基础(一)

    ReentrantLock是Java中java.util.concurrent.locks.Lock的一个实现类,顾名思义它是Java中锁的一种实现,具体一点来说它是Java中一种…

    Java 2023年6月16日
    057
  • SpringBoot 整合Spring Security + JWT 实现前后端分离项目的认证授权

    以下是伪代码,要根据自己的业务自行修改 引入依赖 还用了jwt、redis、fastjson 等 如果添加了就不用添加 SercurityConfig.java User.java…

    Java 2023年5月30日
    055
  • 第一次

    看到很多编程高手都是博客院的账号,我也注册了一个帐号,希望多交流一些技术问题。请大家多多关照。 Original: https://www.cnblogs.com/thinkgem…

    Java 2023年6月7日
    067
  • 【leetcode】239. 滑动窗口最大值

    题目 题解 三种解法 “单调队列”解法 新增、获取最大值 删除 代码 题目 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组…

    Java 2023年6月6日
    063
  • JVM-创建一个对象的详细过程

    Person person=new Person(); 1.现在栈中申请一个自己的栈空间 2.类加载检查 每当使用new操作符创建一个对象时,类加载器都会从常量池中寻找该对象的符号…

    Java 2023年6月6日
    071
  • 玩转 SpringBoot2.x 之整合邮件发送

    序 在实际项目中,经常需要用到邮件通知功能。比如,用户通过邮件注册,通过邮件找回密码等;又比如通过邮件发送系统情况,通过邮件发送报表信息等等,实际应用场景很多。 原文地址:http…

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