Dubbox(Dubbo 改進版)作為高性能 RPC 框架,其啟動初始化過程涉及容器啟動、Spring 集成、配置解析、註冊中心連接、協議服務暴露/引用等核心環節。本文梳理 Provider 和 Consumer 兩條主線的完整調用鏈。
com.alibaba.dubbo.container.Main.main(args)
→ 讀取 dubbo.properties → dubbo.container
→ container.start() → 支持 spring, log4j, jetty 等容器
SpringContainer.java
→ 掃描 classpath*:META-INF/spring/*.xml
→ 解析 dubbo.xsd 自定義標簽
DubboNamespaceHandler.java
→ new DubboBeanDefinitionParser(ServiceBean.class, true)
→ Spring 對 Bean 進行初始化
ServiceBean.afterPropertiesSet()
→ setProvider(), setApplication(), setModule()
→ setRegistries(), setMonitor(), setProtocols(), setPath()
→ export()
ServiceConfig.export()
→ doExportUrlsFor1Protocol()
→ protocol.export() // 關鍵分發點
protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension()
// → Protocol$Adaptive.java (動態生成)
→ ExtensionLoader.loadExtensionClasses()
→ 掃描 META-INF/dubbo/internal/, META-INF/dubbo/, META-INF/services/
→ 讀取配置文件 com.alibaba.dubbo.rpc.Protocol
→ 裝配 filter、listener、mock 等 Wrapper
RegistryProtocol.export()
→ getRegistry() → ZookeeperRegistry → ZookeeperClient
→ registry.subscribe() // 加入監聽列表,接收配置變更通知
RestProtocol.export()
→ doExport()
→ server.start(), server.deploy() // 啟動嵌入式服務器
同 Provider,共用容器機制。
DubboNamespaceHandler.java
→ new DubboBeanDefinitionParser(ReferenceBean.class, false)
ReferenceBean.afterPropertiesSet()
→ ReferenceConfig.init()
→ createProxy()
→ refProtocol.refer()
refProtocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension()
// 同 Provider 擴展加載機制
→ RegistryProtocol.refer()
→ getRegistry() → ZookeeperRegistry
→ doRefer()
→ RegistryDirectory.subscribe()
→ registry.subscribe() // 監聽服務變更
ReferenceConfig.init()
→ createProxy()
→ AbstractProxyFactory.getProxy()
→ JavassistProxyFactory.getProxy()
// 運行時生成 com.alibaba.dubbo.common.bytecode.Proxy 實例
| 模式 | 應用場景 | 關鍵類 |
|---|---|---|
| 適配器/Wrapper | Protocol 擴展鏈:filter、listener、mock 層層包裹 | Protocol$Adaptive |
| 工廠/擴展加載 | ExtensionLoader 動態掃描 @Adaptive 和配置文件 | ExtensionLoader |
| 代理 | Consumer 端生成服務接口代理,透明遠程調用 | JavassistProxyFactory |
| 觀察者 | 註冊中心變更通知、配置動態刷新 | RegistryDirectory、NotifyListener |
| Copy-on-Write | URL 參數設置返回新對象,保證不可變性 | URL.putParameter() |
ExtensionLoader 掃描配置文件和 @Adaptive 註解,實現 Filter/Listener/Mock 的熱插拔putParameter() 返回新對象,線程安全,避免併發修改問題源碼閱讀建議:從 ExtensionLoader 入手理解擴展機制,再追蹤 Protocol$Adaptive 看協議分發,最後深入 RegistryProtocol 看註冊發現邏輯。