Dubbo原始碼分析——擴充套件點機制
Dubbo作為開源框架,必須要提供很多的可擴充套件點。Dubbo的擴充套件點載入採用了微核心外掛式的開發模式,它是比較符合OCP原則。
微核心
由一個外掛生命週期管理容器,構成微核心, 核心不包括任何功能,這樣可以確保所有功能都能被替換,並且框架實現的功能,擴充套件者也一定能做到,以保證平等對待第三方。因此Dubbo框架自身的功能也採用了外掛的方式來實現,不採用任何硬編碼。
通常微核心都會採用Factory,IoC,OSGi等方式管理外掛生命週期,為了減少對spring的依賴,Dubbo放棄使用spring的IoC容器,而採用了Factory方式來管理外掛。
JDK SPI機制
JDK標準的SPI(Service Provider Interface)擴充套件點發現機制,即我們定義了服務介面標準,廠商提供具體的介面實現,JDK通過ServiceLoader類實現SPI機制的服務查詢功能,下面是簡單示例:
首先定義介面
package com.example;
public interface DemoService{
String sayHello();
}
ServiceLoader會遍歷所有jar查詢META-INF/services/com.example.DemoService檔案
A廠商實現
package com.a.example;
public class DemoServiceAImpl implements DemoService{
public String sayHello(){
return "hello 我是廠商A" ;
}
}
在A廠商提供的jar包中的META-INF/services/com.example.DemoService檔案內容為:com.a.example.DemoServiceAImpl
B廠商實現
package com.b.example;
public class DemoServiceBImpl implements DemoService{
public String sayHello(){
return "hello 我是廠商B";
}
}
在B廠商提供的jar包中的META-INF/services/com.example.DemoService檔案內容為:com.b.example.DemoServiceBImpl
ServiceLoader.load(DemoService.class)讀取廠商A、B提供jar包中檔案,獲取介面DemoServie的所有實現類
基於SPI思想的Dubbo擴充套件點機制
Dubbo根據JDK SPI機制的思想實現了自己的擴充套件點機制,位於com.alibaba.dubbo.common.extension包下的ExtensionLoader是Dubbo擴充套件點機制的核心,相當於JDK SPI中的ServiceLoader。
下面我們以Protocol介面實現類的載入為例,來解析ExtensionLoader的載入過程。
Protocol介面
package com.alibaba.dubbo.rpc;
@SPI("dubbo")
public interface Protocol {
int getDefaultPort();
@Adaptive
<T> Exporter<T> export(Invoker<T> invoker) throws RpcException;
@Adaptive
<T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;
void destroy();
}
開啟dubbo原始碼,在dubbo-rpc-api模組的META-INF/dubbo/internal/目錄下,會發現com.alibaba.dubbo.rpc.Protocol檔案,其內容為:
filter=com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper
listener=com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrapper
mock=com.alibaba.dubbo.rpc.support.MockProtocol
而dubbo-rpc-default模組的META-INF/dubbo/internal/com.alibaba.dubbo.rpc.Protocol檔案內容為:
dubbo=com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol
ProtocolFilterWrapper、ProtocolListenerWrapper、MockProtocol、DubboProtocol都是Protocol介面的實現類,com.alibaba.dubbo.rpc.Protocol檔案的格式為:配置名=擴充套件實現類全限定名,多個實現類用換行符分隔。
那麼ExtensionLoader是如何載入Protocol介面的這些實現類的呢?
在ServiceConfig類中有這樣一行程式碼
private static final Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
ExtensionLoader.getExtensionLoader方法
public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
if (type == null)
throw new IllegalArgumentException("Extension type == null");
if(!type.isInterface()) {
throw new IllegalArgumentException("Extension type(" + type + ") is not interface!");
}
if(!withExtensionAnnotation(type)) {
throw new IllegalArgumentException("Extension type(" + type +
") is not extension, because WITHOUT @" + SPI.class.getSimpleName() + " Annotation!");
}
ExtensionLoader<T> loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
if (loader == null) {
EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader<T>(type));
loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
}
return loader;
}
未完待續……
相關推薦
Dubbo原始碼分析——擴充套件點機制
Dubbo作為開源框架,必須要提供很多的可擴充套件點。Dubbo的擴充套件點載入採用了微核心外掛式的開發模式,它是比較符合OCP原則。 微核心 由一個外掛生命週期管理容器,構成微核心, 核心不包括任何功能,這樣可以確保所有功能都能被替換,並且框架實現的功能,
dubbo原始碼分析-ExtensionLoader發現機制和Adaptive註解應用
Dubbo的靈活性體現在每個系統功能點都可以動態擴充套件為新的實現,而且只需要額外配置,不需要修改dubbo原始碼,非常符合面向物件設計的開閉原則,其實現原理利用了JDK5.0的自動發現機制,具體使用相關程式碼是ExtensionLoader 本文目的
Dubbo擴充套件點機制分析
一、擴充套件點配置詳見我在《Java的SPI機制分析》文章中關於Dubbo的SPI機制的介紹,在此不再贅述。二、擴充套件點流程分析之SPI 下面以Container載入的過程為例,來說明SPI擴充套件的實現流程:所有加上@SPI註解的擴充套件點可以有不同的擴充套件,Co
Dubbo原始碼分析(六)Dubbo通訊的編碼解碼機制
Dubbo原始碼分析(一)Dubbo的擴充套件點機制 Dubbo原始碼分析(二)Dubbo服務釋出Export Dubbo原始碼分析(三)Dubbo的服務引用Refer Dubbo原始碼分析(四)Dubbo呼叫鏈-消費端(叢集容錯機制) Dubbo原始碼分析(五)Dubbo呼叫鏈-服務端
Dubbo/Dubbox的服務暴露(二)-擴充套件點機制
上文書留的疑問,這兩句到底在幹啥 Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, regis
Dubbo原始碼實現四:Dubbo中的擴充套件點與SPI
SPI的全稱是ServiceProviderInterface,即服務提供商介面。直白的說,它主要用來實現一個可擴充套件的Java應用。有人會覺得這就是建立在面向介面程式設計下的一種為了使元件可擴充套件或動態變更實現的規範,常見的類SPI的設計有JDBC、JN
dubbo擴充套件點機制
spring是如何啟動容器的 常見的一種在本地使用main方法啟動spring的方法 public static void main(String[] args) throws Exception { ClassPathXmlAp
Dubbo原始碼分析:Dubbo自己實現的IOC
在建立自適應例項時,都會呼叫ExtensionLoader的injectExtension方法: @SuppressWarnings("unchecked") private T createAdaptiveExtension() { try {
Dubbo 原始碼分析 - 服務匯出全過程解析
1.服務匯出過程 本篇文章,我們來研究一下 Dubbo 匯出服務的過程。Dubbo 服務匯出過程始於 Spring 容器釋出重新整理事件,Dubbo 在接收到事件後,會立即執行服務匯出邏輯。整個邏輯大致可分為三個部分,第一是前置工作,主要用於檢查引數,組裝 URL。第二是匯出服務,包含匯出服務到本地 (JV
Dubbo 原始碼分析系列之三 —— 架構原理
1 核心功能 首先要了解Dubbo提供的三大核心功能: Remoting:遠端通訊 提供對多種NIO框架抽象封裝,包括“同步轉非同步”和“請求-響應”模式的資訊交換方式。 Cluster: 服務框架 提供基於介面方法的透明遠端過程呼叫,包括多協議支援,以及
JUnit原始碼分析 - 擴充套件 - 自定義Rule
JUnit Rule簡述 Rule是JUnit 4.7之後新加入的特性,有點類似於攔截器,可以在測試類或測試方法執行前後新增額外的處理,本質上是對@BeforeClass, @AfterClass, @Before, @After等的另一種實現,只是功能上更靈活多變,易於擴充套
Dubbo 原始碼分析 - 自適應北京PK10原始碼出售拓展原理
1.原理我在上一篇文章北京PK10原始碼出售 QQ2952777280【話仙原始碼論壇】hxforum.com 分析了 Dubbo 的 SPI 機制,Dubbo SPI 是 Dubbo 框架的核心。Dubbo 中的很多拓展都是通過 SPI 機制進行載入的,比如 Protocol、Cluster、LoadBal
Dubbo 原始碼分析 - 服務引用
1. 簡介 在上一篇文章中,我詳細的分析了服務匯出的原理。本篇文章我們趁熱打鐵,繼續分析服務引用的原理。在 Dubbo 中,我們可以通過兩種方式引用遠端服務。第一種是使用服務直聯的方式引用服務,第二種方式是基於註冊中心進行引用。服務直聯的方式僅適合在除錯或測試服務的場景下使用,不適合在線上環境使用。因此,本
Dubbo 原始碼分析 - 叢集容錯之 Router
1. 簡介 上一篇文章分析了叢集容錯的第一部分 – 服務目錄 Directory。服務目錄在重新整理 Invoker 列表的過程中,會通過 Router 進行服務路由。上一篇文章關於服務路由相關邏輯沒有細緻分析,一筆帶過了,本篇文章將對此進行詳細的分析。首先,先來介紹一下服務目錄是什麼。服務路由包含一條路由
Dubbo 原始碼分析 - 叢集容錯之 LoadBalance
1.簡介 LoadBalance 中文意思為負載均衡,它的職責是將網路請求,或者其他形式的負載“均攤”到不同的機器上。避免叢集中部分伺服器壓力過大,而另一些伺服器比較空閒的情況。通過負載均衡,可以讓每臺伺服器獲取到適合自己處理能力的負載。在為高負載的伺服器分流的同時,還可以避免資源浪費,一舉兩得。負載均衡可
技術帖 | dubbo原始碼分析 -- 遠端通訊 netty
dubbo 底層通訊選擇了 netty 這個 nio 框架做為預設的網路通訊框架並且通過自定義協議進行通訊。dubbo 支援以下網路通訊框架: Netty(預設) Mina Grizz ly Netty是什麼? ①本質:由JBOSS提供的一個java開源框架(一個jar包)
dubbo原始碼分析-消費端啟動初始化過程-筆記
消費端的程式碼解析是從下面這段程式碼開始的 <dubbo:reference id="xxxService" interface="xxx.xxx.Service"/> ReferenceBean(afterPropertiesSet) ->getObject() ->ge
dubbo原始碼分析-服務端釋出流程-筆記
Spring對外留出的擴充套件 dubbo是基於spring 配置來實現服務的釋出的,那麼一定是基於spring的擴充套件來寫了一套自己的標籤,那麼spring是如何解析這些配置呢?具體細節就不在這裡講解,大家之前在學習spring原始碼的時候,應該有講過。總的來說,就是可以通過spring的擴充套
dubbo原始碼分析-服務端註冊流程-筆記
前面,我們已經知道,基於spring這個解析入口,到釋出服務的過程,接著基於DubboProtocol去釋出,最終呼叫Netty的api建立了一個NettyServer。 那麼繼續沿著RegistryProtocol.export這個方法,來看看註冊服務的程式碼: RegistryProtocol.ex
dubbo原始碼分析-服務呼叫流程-筆記
消費端呼叫過程流程圖 消費端的呼叫過程 消費端介面例項: 服務端接收訊息處理過程 NettyHandler. messageReceived 接收訊息的時候,通過NettyHandler.messageReceived作為入口 @Override public vo