1.發布流程
- 暴露本地服務
- 暴露遠程服務
- 啟動netty
- 連接zookeeper
- 到zookeeper注冊
- 監聽zookeeper
2.官方文檔


3.看輸出日志,就會發現在暴露本地服務之前,有一句很重要的日志

定位到了ServiceBean這個類,這個類是干嘛的?我們來看一下他的繼承體系圖

ApplicationListener.要能敏銳的發現這個關鍵的接口,首先還是要對spring有一定了解,這個就是spring的事件機制(event).什么是事件機制呢?就比如監聽
spring容器初始化完成.那我們就定位到這行日志的位置,往下debug






接下來繼續往下走

進行遍歷呢,因為dubbo是支持多協議的,看文檔原話

下面就到了第三個面試題,也是服務發布的重點,本地暴露和遠程暴露

為什么會有本地暴露和遠程暴露呢?不從場景考慮討論技術的沒有意義是.在dubbo中我們一個服務可能既是Provider,又是Consumer,因此就存在他自己調用自己服務的情況,如果再通過網絡去訪問,那自然是舍近求遠,因此他是有本地暴露服務的這個設計.從這里我們就知道這個兩者的區別
- 本地暴露是暴露在JVM中,不需要網絡通信.
- 遠程暴露是將ip,端口等信息暴露給遠程客戶端,調用時需要網絡通信.

點進ProxyFactory查看源碼

@Adaptive注解打在類上和方法上,他們是有區別的
adaptive設計的目的是為了識別固定已知類和擴展未知類。
1.注解在類上:代表人工實現,實現一個裝飾類(設計模式中的裝飾模式),它主要作用於固定已知類,
目前整個系統只有2個,AdaptiveCompiler、AdaptiveExtensionFactory。
a.為什么AdaptiveCompiler這個類是固定已知的?因為整個框架僅支持Javassist和JdkCompiler。
b.為什么AdaptiveExtensionFactory這個類是固定已知的?因為整個框架僅支持2個objFactory,一個是spi,另一個是spring
2.注解在方法上:代表自動生成和編譯一個動態的Adpative類,它主要是用於SPI,因為spi的類是不固定、未知的擴展類,所以設計了動態$Adaptive類.
例如 Protocol的spi類有 injvm dubbo registry filter listener等等 很多擴展未知類,
它設計了Protocol$Adaptive的類,通過ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(spi類);來提取對象
打在方法上,就會生成動態編譯的Adaptive類,下面就介紹一下怎么看這個動態編譯類的源碼
DEBUG
為什么需要調整成DEBUG

打開DEBUG后,我們重新啟動,就會看到日志有如下輸出,這段就是相關代碼,我們根據包名新建文件,如下


我們在getInvoker方法上打上斷點,重啟一下.



由上圖知道,本地暴露的url是以injvm開頭的,下面來看下遠程暴露
上面講到了getInvoker方法,也就是拿到了Invoker,如果注意到本篇開頭的文檔說明中的那句Dubbo
處理服務暴露的關鍵就在 Invoker 轉換到 Exporter 的過程,就知道,其實這個服務暴露

做的是過濾器操作,詳細看下圖




還利用exporterMap緩存了exporter,key和value參考下圖

整個過程轉化

本地服務暴露結束
參考:https://www.jianshu.com/p/60a9263f2ee2
