免费观看又色又爽又黄的小说免费_美女福利视频国产片_亚洲欧美精品_美国一级大黄大色毛片

朝花夕拾---dubbo源碼分析-創新互聯

前言

該篇博客意在做dubbo啟動調用流程做源碼分析,采用先給出部分結論,然后推導出整個調用流程的過程

創新互聯公司專業為企業提供李滄網站建設、李滄做網站、李滄網站設計、李滄網站制作等企業網站建設、網頁設計與制作、李滄企業網站模板建站服務,十載李滄做網站經驗,不只是建網站,更提供有價值的思路和整體網絡服務。一? 服務發布

dubbo服務的每個標記了@service的類和在xml配置中帶有標簽,均會被解析成ServiceBean,服務發布的故事就從serviceBean這個類開始

首先看一下serviceBean的類繼承關系:

從類繼承圖中,我們發現了幾個重要的接口:

serviceConfig? ? ? ?這個是和dubbo服務發布相關的

ApplicationListener? ? spring的事件相關

InitializingBean? ? ? ?初始化相關

當然最重要的就是ApplicationListener的監聽方法了:

以下是服務發布的幾個重要路徑:

ServiceBean#export();

ServiceConfig#doExport()

doExportUrlsFor1Protocol()

在doExportUrlsFor1Protocol這里就是服務發布的重點了

以上截圖就是dubbo在做服務發布的核心代碼了,這里dubbo使用了動態代理(SPI)+裝飾器模式,完整的構造了一個Invoker和Exporter

DUBBO的SPI:ExtensionLoader? 通過加載指定路徑下,配置的key-value形式的類。同時還支持代理和增強(Wrapper + 裝飾),有興趣的同學可以認真研究一下dubbo的SPI機制,這里只做簡單概括,比如里面2個最重要的代理對象:proxyFacotory,protocol,他們的源碼分別截圖如下:

proxyFactory:

protocol:

從以上截圖不難發現:protocol和proxyFactory的處理邏輯大體類似:通過url獲取指定參數,如果為空,就使用默認值:然后通過ExtensionLoader加載從url中獲取的對象

首先看一下通過proxyFactory獲取的Invoker對象:

想一下,為什么extName是javassist,獲取到的ProxyFactory卻是:StubProxyFactoryWrapper?按照之前說的SPI機制,應該獲取的是:JavassistProxyFactory?

這是因為:在ExtensionLoader#createExtension時

cachedWrapperClasses的寫入是在讀取指定路徑的文件時寫入的,通過判斷加載的類是否有,包含相同接口的構造器做判斷的:

這里真正干活的還是:JavassistProxyFactory

所以,真正構建Invoker的代碼如下:

其實就是構建了一個AbstractProxyInvoker,其中的Wrapper簡單的理解成一個包裝類即可(這就是dubbo動態生成類的方式,其實沒有什么多大的技術問題,只是覺得就是裝X而已),代碼如下:

再來看看export過程:

同樣的,extName是registry,實際的加載類是:ProtocolListenerWrapper

而ProtocolListenerWrapper里面包裝的protocol是:ProtocolFilterWrapper,而ProtocolFilterWrapper里面包裝的protocol是RegistryProtocol(真正干活的)

可以看下最終生成的Exporter的結構:

其中DubboExporter是在DubboProtocol類中構造的,還是和之前一樣,通過裝飾器,一層一層遞進構造的:

至此,服務的發布已經完成,其中有些步驟跳躍可能稍微大一點,感興趣的同學請自行本地調試?

二? 服務調用

dubbo中每一個標記了@Reference域和在xml中配置了的元素,均會被解析成一個ReferenceBean

首先,看一下ReferenceBean的類關系:

其中FactoryBean就是spring的工廠Bean,和ServiceBean類似,ReferenceBean也繼承一個Config類,如上,服務調用的故事就從ReferenceConfig的#get()開始

ReferenceBean#getObject()

? ReferenceConfig#get()

init();

相信使用過動態代理的同學都知道,使用動態代理的使用,通過代理對象,在自己的邏輯里面就可以"為所欲為"了。dubbo在服務調用的時候也是這么干的!

init方法就是創建代理的入口,方法比較長,咱們撿重點說,前面就是一些校驗,判斷,最主要的方法入口:

創建代理需要一個map,看看這個map里面的信息如下:

下面正式開啟創建代理的過程,老規矩,忽略掉無關精要的代碼,直接上干貨:

這個refprotocol就是在前面截圖的那個Protocol$Adaptive代碼,這里咱們為了方便調試,直接把代碼替換一下:

和服務發布過程一樣,extName是registry,獲取到的實例卻是:ProtocolListenerWrapper(裝飾器模式)

大概裝飾層級就是:

ProtocolListenerWrapper

?ProtocolFilterWrapper

RegistryProtocol

在RegistryProtocol是真正干活的地方:

一路debug調試,最終返回到創建代理的代碼入口:

在之前的服務發布過程中,我們已經帖出了proxyFactory的相關代碼(dubbo這里做了動態加載,不利于調試,咱們做個替換)

替換后的代碼如下:

現在將要進行真正的動態代理的創建過程:

和其他的Adaptive一樣,真正干活的是JavassistProxyFactory,使用StubProxyFactoryWrapper做裝飾

真正干活的是JavassistProxyFactory

看到這里,熟悉動態代理的同學已經很熟悉了。真正的執行邏輯就在InvokerInvocationHandler里面了,在這個handler里面是不是為所欲為呢?

截圖如下:

由截圖可知,在InvokerInvocationHandler里面真正調用就是使用invoker調用邏輯

當真正調用時,一路dubug

這個Invoker也是一個裝飾器。咱們一步一步調試進入:

首先:MockClusterInvoker

真正的調用又委托給了:FailoverClusterInvoker

從以上代碼注釋中可以看出,FailoverClusterInvoker,通過負載均衡器選擇"最優"的Invoker發起遠程調用

這里選擇了:RegistryDirectory$DeleteInvoker其實就是一個InvokerWrapper

真正干活的是ListenerInvokerWrapper

繼續遞進:調用ProtocolFilterWrapper

最終來到了ProtocolFilterWrapper的匿名內部類:

把調用過程委托給了filter調用鏈路,至此,Invoker的使命完成了。相信更深的調用邏輯,通過分析Filter就能找到答案了

三? FailOverClusterInvoker選擇Invoker過程既FilterChain調用鏈的組裝

在第二節中,有分析服務發布調用過程,最紅是委托給了Filter調用。我們在分析的時候,有意的忽略掉了部分調用細節,只是為了更好的梳理出整個調用鏈路。下面就分析一下在負載均衡器選擇Invoker的詳細邏輯

故事的開始當然是從FailoverClusterInvoker的invoke開始,FailoverClusterInvoker沒有自己實現invoke,其父類AbstractClusterInvoker實現了:

尋找Invoker的時候委托給了RegistryDirectory:

最終的Invoker尋找在RegistryDirectory里面維護的一個字段:methodInvokerMap里面查詢即可

查詢到全量的數據之后,就通過負載均衡器選擇,完成Invoker的選擇

那RegistryDirectory的methodInvokerMap又是在什么時候獲得調用方法和Invoker的對應關系的呢?

通過跟蹤字段的調用來源

最終確認: RegistryProtocol#doRefer時會調用到如上方法里面,生成method和Invokers的對應關系

以上,將服務發布,服務調用的過程做了較為粗略和完整的說明

四 結論證明

在前言部分有說過,先給出部分結論:

1 所有被標記了@service和使用標記的元素,均會被spring解析成ServiceBean

2 所有被標記了@Reference和使用的元素,均會被spring解析成ReferenceBean

這是怎么做到的呢?

在結合xml使用的時候,dubbo有引入DubboNamespaceHandler,該handler會解析相關的xml標簽,完成如上功能:

而在springboot應用中,dubbo有引入:ServiceAnnotationBeanPostProcessor

該類是一個前置處理器,會掃描@service標記的類,通過構建BeanDefinitionBuilder完成ServiceBean的注冊:

同樣的:springboot應用中引入了ReferenceAnnotationBeanPostProcessor

ReferenceAnnotationBeanPostProcessor是一個后置處理器,在Bean初始化時會被調用,注入相應的代理類

創作不易,如果對你有幫助,請點贊+收藏!

你是否還在尋找穩定的海外服務器提供商?創新互聯www.cdcxhl.cn海外機房具備T級流量清洗系統配攻擊溯源,準確流量調度確保服務器高可用性,企業級服務器適合批量采購,新人活動首月15元起,快前往官網查看詳情吧

文章名稱:朝花夕拾---dubbo源碼分析-創新互聯
分享網址:http://m.newbst.com/article42/deoghc.html

成都網站建設公司_創新互聯,為您提供小程序開發電子商務網頁設計公司App開發網站排名虛擬主機

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

成都app開發公司