程序猿成长之路少不了要学习和分析源码的。最近难得能静得下心来,就针对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的 |
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,而调用的协议都是可变可扩展的。观察者模式就更随处可见了。