Dubbo——擴展點註解

擴展點註解:@SPI

@SPI註解可以使用在類、接口和枚舉類上,Dubbo框架中都是使用在接口上。它的主要作用就是標記這個幾口是一個Dubbo SPI接口,即是一個擴展點,可以有多個不同的內置或用戶定義的實現。運行時需要通過配置找到具體的實現類。

在這裏插入圖片描述
可以看到SPI註解有一個value屬性,通過這個屬性,我們可以傳入不同的參數來設置這個接口額默認實現類。

例如,我們可以看到Transporter接口使用Netty作爲默認實現:
在這裏插入圖片描述
Dubbo中很多地方通過getExtension(Class<T> type, String name)來獲取擴展點接口的具體實現,此時會傳入Class做校驗,判斷是否是接口,以及是否有@SPI註解,兩者缺一不可。

擴展點自適應註解:@Adaptive

@Adaptive註解可以標記在類、接口、枚舉類和方法上,但是在整個Dubbo框架中,只有幾個地方使用在類級別上,如AdaptiveExtensionFactory和AdaptiveCompiler,其餘都標註在方法上。

如果標註在接口的方法上,即方法級別註解,則可以通過參數動態獲得實現類。方法級別註解在第一次getExtension時,會自動生成和編譯一個動態的Adaptive類,從而達到動態實現類的效果。

例如:Transporter接口在bind和connect兩個方法上添加了@Adaptive註解,如下所示:
在這裏插入圖片描述
Dubbo在初始化擴展點時,會生成一個Transporter#Adaptive類,裏面會實現這兩個方法,方法裏會有一些抽象的通用邏輯,通過@Adaptive中傳入的參數,找到並調用真正的實現類。自動生成的代碼中實現了很多通用的功能,最終會調用真正的接口實現。

當該註解放在實現類上,則整個實現類會直接作爲默認實現,不再自動生成代碼清單。在擴展點接口的多個實現裏,只能有一個實現上可以加@Adaptive註解。如果多個實現類中都有該註解,則會拋出異常:More than 1 adaptive class found

在這裏插入圖片描述

該註解也可以傳入value參數,是一個數組。Adaptive可以傳入多個key值,在初始化Adaptive註解的接口時,會先對傳入的URL進行key值匹配,第一個key沒匹配上則匹配第二個,以此類推。直到所有的key匹配完畢,如果還沒有匹配到,則會使用"駝峯規則"匹配,如果也沒有匹配到,則會拋出IllegalStateException異常。

駝峯規則:
如果包裝類(Wrapper)沒有用Adaptive指定key值,則Dubbo會自動把接口名稱根據駝峯大小寫分開,並用"."符號連接起來,以此來作爲默認實現類的名稱,如org.apache.dubbo.xxx.YyyInvokerWrapper中的YyyInvokerWrapper會被轉換爲yyy.invoker.warpper

爲什麼有些實現類上會標註@Adaptive?
放在實現類上,主要是爲了直接固定對應的實現而不需要動態生成代碼實現,就像策略模式直接確定實現類。

在代碼中的實現方式是:ExtensionLoader中會緩存兩個與@Adaptive有關的對象:

  1. 一個緩存在cachedAdaptiveClass中,即Adaptive具體實現類的Class類型;
  2. 另外一個緩存在cachedAdaptiveInstance中,即Class的具體實例化對象;

在擴展點初始化時,如果發現實現類有@Adaptive註解,則直接賦值給cachedAdaptiveClass,後續實例化類的時候,就不會再動態生成代碼,直接實例化cachedAdaptiveClass,並把實例緩存到cachedAdativeInstance中。

如果註解在接口方法上,則會根據參數,動態獲得擴展點的實現,會生成Adaptive類,再緩存到cachedAdaptiveInstance中。

擴展點自動激活註解:@Activate

@Activate可以標記在類、接口、枚舉類和方法上。主要使用在有多個擴展點實現、需要根據不同條件被激活的場景中,如Filter需要多個同時激活,因爲每個Filter實現的是不同的功能。

@Activate可傳入的參數:

參數名 效果
String[] group() URL中的分組如果匹配則激活,則可以設置多個
String[] value() 查找URL中如果含有該key值,則會激活
String[] before() 填寫擴展點列表,表示那些擴展點要在本擴展點之前
String[] after() 同上,表示哪些需要在本擴展點之後
int order() 整型,直接的排序信息
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章