在Dubbo可擴展機制實戰中,咱們瞭解了Dubbo擴展機制的一些概念,初探了Dubbo中LoadBalance的實現,並本身實現了一個LoadBalance。是否是以爲Dubbo的擴展機制很不錯呀,接下來,咱們就深刻Dubbo的源碼,一睹廬山真面目。緩存
ExtentionLoader是最核心的類,負責擴展點的加載和生命週期管理。咱們就以這個類開始吧。
Extension的方法比較多,比較經常使用的方法有:app
public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type)
public T getExtension(String name)
public T getAdaptiveExtension()
比較常見的用法有:dom
LoadBalance lb = ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(loadbalanceName)
RouterFactory routerFactory = ExtensionLoader.getExtensionLoader(RouterFactory.class).getAdaptiveExtension()
說明:在接下來展現的源碼中,我會將無關的代碼(好比日誌,異常捕獲等)去掉,方便你們閱讀和理解。this
*1. getExtensionLoader方法
這是一個靜態工廠方法,入參是一個可擴展的接口,返回一個該接口的ExtensionLoader實體類。經過這個實體類,能夠根據name得到具體的擴展,也能夠得到一個自適應擴展。spa
public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) { // 擴展點必須是接口 if (!type.isInterface()) { throw new IllegalArgumentException("Extension type(" + type + ") is not interface!"); } // 必需要有@SPI註解 if (!withExtensionAnnotation(type)) { throw new IllegalArgumentException("Extension type without @SPI Annotation!"); } // 從緩存中根據接口獲取對應的ExtensionLoader // 每一個擴展只會被加載一次 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; } private ExtensionLoader(Class<?> type) { this.type = type; objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension()); }
*2. getExtension方法日誌
public T getExtension(String name) { Holder<Object> holder = cachedInstances.get(name); if (holder == null) { cachedInstances.putIfAbsent(name, new Holder<Object>()); holder = cachedInstances.get(name); } Object instance = holder.get(); // 從緩存中獲取,若是不存在就建立 if (instance == null) { synchronized (holder) { instance = holder.get(); if (instance == null) { instance = createExtension(name); holder.set(instance); } } } return (T) instance; }
getExtention方法中作了一些判斷和緩存,主要的邏輯在createExtension方法中。咱們繼續看createExtention方法。code
private T createExtension(String name) { // 根據擴展點名稱獲得擴展類,好比對於LoadBalance,根據random獲得RandomLoadBalance類 Class<?> clazz = getExtensionClasses().get(name); T instance = (T) EXTENSION_INSTANCES.get(clazz); if (instance == null) { // 使用反射調用nesInstance來建立擴展類的一個示例 EXTENSION_INSTANCES.putIfAbsent(clazz, (T) clazz.newInstance()); instance = (T) EXTENSION_INSTANCES.get(clazz); } // 對擴展類示例進行依賴注入 injectExtension(instance); // 若是有wrapper,添加wrapper Set<Class<?>> wrapperClasses = cachedWrapperClasses; if (wrapperClasses != null && !wrapperClasses.isEmpty()) { for (Class<?> wrapperClass : wrapperClasses) { instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance)); } } return instance; }
createExtension方法作了如下事情:
*1. 先根據name來獲得對應的擴展類。從ClassPath下META-INF
文件夾下讀取擴展點配置文件。router
*2. 使用反射建立一個擴展類的實例接口
*3. 對擴展類實例的屬性進行依賴注入,即IoC。生命週期
*4. 若是有wrapper,添加wrapper,即AoP。
下面咱們來重點看下這4個過程 *1. 根據name獲取對應的擴展類 先看代碼: