程序猿成长之路少不了要学习和分析源码的。最近难得能静得下心来,就针对dubbox为目标开始进行源码分析。

【服务提供方】

步骤 调用顺序 备注
容器启动

com.alibaba.dubbo.container.Main.main(args);
dubbo.properties -> dubbo.container -> container.start()
container -> spring, log4j, jetty...

[dubbo-container-spring] SpringContainer.java -> [服务提供方]classpath*:META-INF/spring/*.xml -> dubbo.xsd

spring的 ApplicationContext介绍

bean初始化

<dubbo:service>等自定义标签 -> [dubbo-config-spring] DubboNamespaceHandler.java
 -> new DubboBeanDefinitionParser(ServiceBean.class, true)

spring对bean的初始化操作

[dubbo-config-spring] ServiceBean.java -> afterPropertiesSet()
-> setProvider(), setApplication(), setModule(), setRegistries, setMonitor(), setProtocols, setPath() -> export()

自定义标签的解析和初始化
连接注册中心

ServiceBean.export() -> ServiceConfig.java -> doExportUrlsFor1Protocol() -> 暴露协议protocol.export()

protocol=ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension()---Protocol$Adaptive.java
-> ExtensionLoader.loadExtensionClasses() -> loadFile()
-> META-INF/dubbo/internal/,META-INF/dubbo/,META-INF/services/
-> [举例dubbo-rpc-api] 配置文件com.alibaba.dubbo.rpc.Protocol
-> filter,listener,mock -> 各类的export()

protocol.export()调用链 -> [dubbo-registry-api] RegistryProtocol.export()
-> getRegistry()---(ZookeeperRegistry.java -> 扩展的ZookeeperClient)
-> registry.subscribe()加入监听列表

注册到注册中心,
并加入监听列表监听注册中心的消息通知。
启动协议服务器 protocol.export()调用链 -> [dubbo-rpc-rest] RestProtocol.export()
-> doExport() -> server.start(), server.deploy()
根据相应协议启动相应服务器

【服务使用方】

步骤 调用顺序 备注
容器启动 参考服务提供方  同provider
bean初始化

<dubbo:reference>等自定义标签 -> [dubbo-config-spring] DubboNamespaceHandler.java
-> new DubboBeanDefinitionParser(ReferenceBean.class, false)

 同provider
连接注册中心

ReferenceBean.java -> afterPropertiesSet() -> ReferenceConfig.init() -> createProxy() -> refprotocol.refer()

refprotocol=ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension()---Protocol$Adaptive.java
-> ExtensionLoader.loadExtensionClasses() -> loadFile()
-> META-INF/dubbo/internal/,META-INF/dubbo/,META-INF/services/
-> [举例dubbo-rpc-api] com.alibaba.dubbo.rpc.Protocol -> filter,listener,mock -> 各类的refer()

protocol.refer()调用链 -> [dubbo-registry-api] RegistryProtocol.refer()
-> getRegistry()---(ZookeeperRegistry.java -> 扩展的ZookeeperClient) -> doRefer()
-> RegistryDirectory.subscribe() -> registry.subscribe()

 同provider
服务接口初始化

ReferenceConfig.init() -> createProxy()
-> AbstractProxyFactory.getProxy() -> JavassistProxyFactory.getProxy()

service接口在实际运行时是 com.alibaba.dubbo.common.bytecode.Proxy 类的实例

 同provider

总结与收获

很多细节由于时间关系没有展开,比如重试机制,比如比较重要的类的整理。整个分析的过程还是很多收获与启发的。

比如url.putParameter()每次设置参数却返回了一个新的对象,算是一种copyOnWrite的简单实现。

又比如几个比较重要的类都通过ExtensionLoader实现了动态扩展,可以理解为一种引擎或一种类加载器扩展,启动时动态扫描@Adaptive注解和配置文件,所以各个模块只要修改配置就可以实现filter, listener和mock的扩展。

再比如,典型的代理模式的应用,consumer都是通过反射生成服务接口的代理实例,实现远程调用provider,而调用的协议都是可变可扩展的。观察者模式就更随处可见了。

dubbox源码分析(一)-服务的启动与初始化的更多相关文章

  1. Netty源码分析之服务端启动过程

    一.首先来看一段服务端的示例代码: public class NettyTestServer { public void bind(int port) throws Exception{ EventL ...

  2. zookeeper源码分析之一服务端启动过程

    zookeeper简介 zookeeper是为分布式应用提供分布式协作服务的开源软件.它提供了一组简单的原子操作,分布式应用可以基于这些原子操作来实现更高层次的同步服务,配置维护,组管理和命名.zoo ...

  3. Netty源码分析之服务端启动

    Netty服务端启动代码: public final class EchoServer { static final int PORT = Integer.parseInt(System.getPro ...

  4. zookeeper源码分析之四服务端(单机)处理请求流程

    上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...

  5. Envoy 源码分析--程序启动过程

    目录 Envoy 源码分析--程序启动过程 初始化 main 入口 MainCommon 初始化 服务 InstanceImpl 初始化 启动 main 启动入口 服务启动流程 LDS 服务启动流程 ...

  6. zookeeper源码分析之五服务端(集群leader)处理请求流程

    leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...

  7. Netty 4源码解析:服务端启动

    Netty 4源码解析:服务端启动 1.基础知识 1.1 Netty 4示例 因为Netty 5还处于测试版,所以选择了目前比较稳定的Netty 4作为学习对象.而且5.0的变化也不像4.0这么大,好 ...

  8. SpringBoot源码分析之SpringBoot的启动过程

    SpringBoot源码分析之SpringBoot的启动过程 发表于 2017-04-30   |   分类于 springboot  |   0 Comments  |   阅读次数 SpringB ...

  9. Spring源码分析专题 —— IOC容器启动过程(上篇)

    声明 1.建议先阅读<Spring源码分析专题 -- 阅读指引> 2.强烈建议阅读过程中要参照调用过程图,每篇都有其对应的调用过程图 3.写文不易,转载请标明出处 前言 关于 IOC 容器 ...

  10. neo4j源码分析1-编译打包启动

    date: 2018-03-22 title: "neo4j源码分析1-编译打包启动" author: "邓子明" tags: - 源码 - neo4j - 大 ...

随机推荐

  1. fix the issue that disk space is not the size that aws ec2 have.

    在申请aws ec2时,按照向导,在选择存储的时候默认硬盘大小是 8 G,这时候可以根据自己的需要输入一个合适的数字,例如100.完成向导并启动ec2 instance 后登陆机器.使用命令: df ...

  2. 使用Redis实现锁(支持分布式应用)(整理网络资料)

    使用Redis实现锁(支持分布式应用) 1.    简介 使用Redis指令setnx.expire.getset等操作实现互斥资源的访问 本文内容来着网络整理,参考: http://www.linu ...

  3. 【转】selenium自动化测试用例需要关注的几点(一)

    自动化测试设计简介  注:参看文章地址 我们在本章提供的信息,对自动化测试领域的新人和经验丰富的老手都是有用的.本篇中描述最常见的自动化测试类型, 还描述了可以增强您的自动化测试套件可维护性和扩展性的 ...

  4. 关于重绘and重排

    在研究CSS3动画性能的时候,看到了重排两个字. 突然想到自己虽然听说过这么个东东,但一直也没深入研究之. 趁着当下正好有研究的劲头,所以一不做二不休,把这个point也给学习了. 同样是一番查找资料 ...

  5. D3介绍

    D3介绍 D3是用来做web页面可视化的组件,其官方网址为http://d3js.org 安装 D3类库的文件只有一个d3.js.下载后直接在html的<script>标签中引用此js就可 ...

  6. deblurGAN

    -- main.py -- util.py -- data_loader.py -- mode.py -- DeblurGAN.py -- vgg19.py -- layer.py -- vgg19. ...

  7. Description Resource Path Location Type web.xml is missing and <failOnMissingWebXml> is set to true

    点击Deployment Descriptor 选择Generate Deployment Descriptor Stub. 就会在 src/main/webapp 生成WEB-INF并且有web.x ...

  8. 任意表格(table)实现拖动列(column)改变列大小

    直接上代码吧,原理可以看我上一篇博文.本实现基于jquery,完美实现拖动改变表格的列大小功能,只需将代码放置在你页面的底部即可(jquery必须先引入). $(function () { var i ...

  9. flask 简易注册登陆

    db.py import MySQLdb conn = MySQLdb.connect(', 'test1') cur = conn.cursor() def addUser (username,pa ...

  10. js-js和HTML的两种结合方式

    第一种: - 使用一个标签 <script type="text/javascript"> js代码; </script> 第二种: - 使用script标 ...