程序猿成长之路少不了要学习和分析源码的。最近难得能静得下心来,就针对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. Unity QualitySettings.shadows 阴影

    QualitySettings.shadows 阴影 public static ShadowQuality shadows; Description 描述: 要使用的实时阴影类型. 这就决定了应该使 ...

  2. 如何在cmd窗口里快速且正确打开任意位置路径(各版本windows系统都适合)(图文详解)(博主推荐)

    问题的由来 有时候,我们很苦恼,总是先系统键 + R,然后再去手动敲.尤其对win7系统比较麻烦 解决办法 方法一:复制路径(这点对win10系统做得好,直接可以复制) ,win7系统的话可能还需要设 ...

  3. frames的对象兼容性获取以及跨域实现数据交换(js文件的加载判断)

    1.document.frames()与document.frames[]的区别 <html> <body> <iframe id="ifr_1" n ...

  4. lua热重载

    热重载,就是不重新开unity让代码的变化直接看出来,一般在开发时候使用 lua中通过require导入的文件,最终都存在package.loaded这个table中.require会判断是否文件已经 ...

  5. Linux下安装jdk1.6

    Linux中JDK1.6的安装和配置方法 一.安装 创建安装目录,在/usr/java下建立安装路径,并将文件考到该路径下: mkdir /usr/java 1.jdk-6u11-linux-i586 ...

  6. leetcode_173【二叉搜索树迭代器】

    实现一个二叉搜索树迭代器.你将使用二叉搜索树的根节点初始化迭代器. 调用 next() 将返回二叉搜索树中的下一个最小的数. 示例: BSTIterator iterator = new BSTIte ...

  7. cut、grep和排序命令

    1.cut 对于行进行操作 cut -d ':' -f 2 以':'为分隔符,切出第二部分的所有行 cut -c 12- 从第12字符往后的字符所有行 2.grep grep '选取的串' 选出所有含 ...

  8. 关于vue的常识问题及解决方法

    一.VSCode开发必备插件 1.Beautify:语法高亮: 2.Bracket Pair Colorizer :对括号对进行着色: 3.ESLint:ESLint插件,高亮提示: 4.HTML C ...

  9. 使用Having子句

    Having 子句与where子句的功能类似,都是对行进行筛选.但是,where搜索条件是在分组操作之前对记录进行筛选,然后再由group BY 对筛选后符合条件的行进行分组:而Having搜索条件则 ...

  10. Oracle OCI操作UDT相关学习(二)

    沿用 Oracle OCI操作UDT相关学习 一文中定义的类型和表. 1.更改数据 在sqldeveloper 中更新数据, update dxl.cust set addr.street='a11' ...