當前位置:編程學習大全網 - 編程語言 - dubbo泛化調用使用及原理解析

dubbo泛化調用使用及原理解析

通常我們想調用別人的dubbo服務時,我們需要在項目中引入對應的jar包。而泛化調用的作用是,我們無需依賴相關jar包,也能調用到該服務。

這個特性壹般使用在網關類項目中,在業務開發中基本不會使用。

假設我現在要調用下面的接口服務

在xml文件做以下配置

然後註入使用

在兩種調用方式中,我們都需要使用被調用接口的字符串參數生成GenericService,通過GenericService的$invoke間接調用目標接口的接口。

$invoke的三個參數分別為,方法名,方法參數類型數組,方法參數數組。

可以看到泛化調用的壹個復雜性在於$invoke的第三個參數的組裝,下面介紹幾種復雜入參的調用方式

首先豐富提供者接口

與入參相似,雖然$invoke的返回定義為Object,實際上針對不同類型有不同的返回。

泛化調用和直接調用在消費者者端,在 使用上的區別 是,我們調用服務時使用的接口為GenericService,方法為$invoker。在 底層的區別 是,消費者端發出的rpc報文發生了變化。

在使用上,不管哪種配置方式,我們都需要配置generic=true

設置generic=true後,RefereceConfig的interfaceClass會被強制設置為GenericService

這也使得我們的RefereanceBean返回的是GenericService類型的代理。

生成的代理是GenericService的代理只是我們使用方式上的變化,更為核心的是,底層發送的rpc報文發生了什麽變化。

Dubbo的rpc報文分為header和body兩部分。我們這邊只需要關註body部分。構造邏輯如下

那麽我們通過直接調用與泛化調用ByeService的bye方法在報文上有啥區別呢?

我壹開始以為報文中的path是GenericeService,其實並沒有,path就是我們調用的目標方法。

path來源?todo

而報文中的方法名,方法參數類型以及具體參數,還是按照GenericeService的$invoke方法入參傳遞的。

這麽個二合壹的報文,發送到提供者那邊,它估計也會很懵逼,我應該怎麽執行?

所以針對泛化調用報文還會把generic=true放在attchment中傳遞過去

具體邏輯在GenericImplFilter中。

GenericImplFilter中有很多其他邏輯,比如泛化調用使用的序列化協議,正常接口走泛化調用的模式,我們只需要設置attachment的那部分。

知道消費者端報文發生了什麽變化,那麽接下來就去看提供者端如何處理這個改造後的報文。

總結壹下ReferenceConfig中interfaceClass和interfaceName的區別?(這道面試題好像不錯)

interfaceClass用於指定生成代理的接口

interfaceName用於指定發送rpc報文中的path(告訴服務端我要調用那個服務)

消費者泛化調用的rpc報文傳遞到提供者還不能直接使用,雖然path是對的,但是實際的方法名,參數類型,參數要從rpc報文的參數中提取出來。

GenericFilter就是用來做這件事情。

在提供者這邊,針對泛化調用的邏輯全部封裝到了GenericFilter,解耦的非常好。

註意第4個條件,壹開始很疑惑,後來發現rpc報文中的path是目標接口的,這邊invoker.getInterface()返回的肯定就是實際接口了

這邊有個疑問,為什麽這邊還要再次反序列化壹次,netty不是有decoder麽

嗯,妳別忘了,針對壹個POJO妳傳過來是壹個Map,從Map轉換為POJO需要這邊進壹步處理。

這邊需要註意壹下!!針對接口的泛化調用,拋出的異常都會經過GenericException包裝壹下。

從功能上來看,泛化調用提供了在沒有接口依賴情況下進行的解決方案,豐富框架的使用場景。

從設計上來看,泛化調用的功能還是通過擴展的方式實現的,侵入性不強,值得學習借鑒。

  • 上一篇:江西南昌研究生編代碼有償幫搶HPV九價疫苗,他的行為合法嗎?
  • 下一篇:2021年最流行的臥室門圖片2021年新款臥室門圖片欣賞
  • copyright 2024編程學習大全網