Dubbo 框架在初始化和通信過程中使用了多種設計模式,可靈活控制類加載、權
限控制等功能。
工廠模式
Provider 在 export 服務時,會調用 ServiceConfig 的 export 方法。ServiceConfig
中有個字段:
private static final Protocol protocol =
ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtensi
on();
Dubbo 里有很多這種代碼。這也是一種工廠模式,只是實現類的獲取采用了 JDK
SPI 的機制。這么實現的優點是可擴展性強,想要擴展實現,只需要在 classpath
下增加個文件就可以了,代碼零侵入。另外,像上面的 Adaptive 實現,可以做到
調用時動態決定調用哪個實現,但是由於這種實現采用了動態代理,會造成代碼
調試比較麻煩,需要分析出實際調用的實現類。
裝飾器模式
Dubbo 在啟動和調用階段都大量使用了裝飾器模式。以 Provider 提供的調用鏈為
例,具體的調用鏈代碼是在 ProtocolFilterWrapper 的 buildInvokerChain 完成
的,具體是將注解中含有 group=provider 的 Filter 實現,按照 order 排序,最
后的調用順序是:
EchoFilter -> ClassLoaderFilter -> GenericFilter -> ContextFilter ->
ExecuteLimitFilter -> TraceFilter -> TimeoutFilter -> MonitorFilter ->
ExceptionFilter
更確切地說,這里是裝飾器和責任鏈模式的混合使用。例如,EchoFilter 的作用是
判斷是否是回聲測試請求,是的話直接返回內容,這是一種責任鏈的體現。而像
ClassLoaderFilter 則只是在主功能上添加了功能,更改當前線程的 ClassLoader,
這是典型的裝飾器模式。
觀察者模式
Dubbo 的 Provider 啟動時,需要與注冊中心交互,先注冊自己的服務,再訂閱自
己的服務,訂閱時,采用了觀察者模式,開啟一個 listener。注冊中心會每 5 秒定
時檢查是否有服務更新,如果有更新,向該服務的提供者發送一個 notify 消息,
provider 接受到 notify 消息后,即運行 NotifyListener 的 notify 方法,執行監
聽器方法。
動態代理模式
Dubbo 擴展 JDK SPI 的類 ExtensionLoader 的 Adaptive 實現是典型的動態代理
實現。Dubbo 需要靈活地控制實現類,即在調用階段動態地根據參數決定調用哪
個實現類,所以采用先生成代理類的方法,能夠做到靈活的調用。生成代理類的
代碼是 ExtensionLoader 的 createAdaptiveExtensionClassCode 方法。代理類
的主要邏輯是,獲取 URL 參數中指定參數的值作為獲取實現類的 key。