Dubbo IOC

在Dubbo中, 無論是通過name 獲取指定擴展類, 還是自適應擴展,都會在加載完擴展,進行一次依賴注入,我們可以把這個稱爲Dubbo的IOC機制。
例如:

private T createExtension(String name) {
    // throws any possible exception in loading period.
    findException(name);
    Class<?> clazz = getExtensionClasses().get(name);
    if (clazz == null) {
        throw noExtensionException(name);
    }
    try {
        T instance = (T) EXTENSION_INSTANCES.get(clazz);
        if (instance == null) {
            EXTENSION_INSTANCES.putIfAbsent(clazz, clazz.newInstance());
            instance = (T) EXTENSION_INSTANCES.get(clazz);
        }
        injectExtension(instance);
        Set<Class<?>> wrapperClasses = cachedWrapperClasses;
        // 這裏會循環注入 Wrapper類最後返回的instance 是多個wrapper包裹之後的instance
        if (CollectionUtils.isNotEmpty(wrapperClasses)) {
            for (Class<?> wrapperClass : wrapperClasses) {
                // 注意這裏 IOC操作
                instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
            }
        }
        return instance;
    } catch (Throwable t) {
        throw new IllegalStateException("Extension instance (name: " + name + ", class: " +
                type + ") couldn't be instantiated: " + t.getMessage(), t);
    }
}

T) wrapperClass.getConstructor(type).newInstance(instance)
是利用反射進行實例化。他的最外層injectExtension方法,所做的就是Dubbo的IOC,將擴展中的屬性進行賦值。接下來我們看一下他的實現

private T injectExtension(T instance) {
    try {
        if (objectFactory != null) {
            // 便利所有方法
            for (Method method : instance.getClass().getMethods()) {
                // 尋找set方法
                if (method.getName().startsWith("set")
                        && method.getParameterTypes().length == 1
                        && Modifier.isPublic(method.getModifiers())) {
            
                    Class<?> pt = method.getParameterTypes()[0];
                    try {
                        // 獲取屬性名稱
                        String property = method.getName().length() > 3 ? method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4) : "";
                        // 從對象工廠中獲取,此類型,此名稱的擴展的對象
                        Object object = objectFactory.getExtension(pt, property);
                        if (object != null) {
                            // 執行setter方法,完成 IOC操作
                            method.invoke(instance, object);
                        }
                    } catch (Exception e) {
                        logger.error("fail to inject via method " + method.getName()
                                + " of interface " + type.getName() + ": " + e.getMessage(), e);
                    }
                }
            }
        }
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
    }
    return instance;
}

遍歷出類中所有的方法,尋找其中的set方法,根據方法命名獲取到需要從容器內搜索的對象的名稱,如果能搜索到,就利用反射進行注入。邏輯很清晰,唯一的疑惑點就是,根據名稱和類型搜索相應的對象的邏輯,也就是 Object object = objectFactory.getExtension(pt, property)
objectFactory是怎麼來的呢?

private final ExtensionFactory objectFactory; 這是一個final變量,不可變,那我們去看他的構造方法去

private ExtensionLoader(Class<?> type) {
    this.type = type;
    objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
}

很明顯這是在我們在開頭 通過接口的class 獲取 ExtentionLoader的時候,創建的
ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension()); 獲取到的是 AdaptiveExtensionFactory的實例,因爲他的類上帶有 @Adaptive註解.

@Adaptive
public class AdaptiveExtensionFactory implements ExtensionFactory {

    private final List<ExtensionFactory> factories;

    public AdaptiveExtensionFactory() {
        ExtensionLoader<ExtensionFactory> loader = ExtensionLoader.getExtensionLoader(ExtensionFactory.class);
        List<ExtensionFactory> list = new ArrayList<ExtensionFactory>();
        for (String name : loader.getSupportedExtensions()) {
            list.add(loader.getExtension(name));
        }
        factories = Collections.unmodifiableList(list);
    }

    @Override
    public <T> T getExtension(Class<T> type, String name) {
        for (ExtensionFactory factory : factories) {
            T extension = factory.getExtension(type, name);
            if (extension != null) {
                return extension;
            }
        }
        return null;
    }

}

所以最後就是它作爲擴展類,也就是objectFactory的實例對象。所以當調用objectFactory.getExtension 實際執行的是AdaptiveExtensionFactory的 getExtension方法.
我們可以看到他是從factories 裏去拿, factories是構造函數中初始化的.

list.add(loader.getExtension(name));
那麼我們在common子工程下,找到如下的SPI擴展文件 META-INF/dubbo/internal/org.apache.dubbo.common.extension.ExtensionFactory

adaptive=org.apache.dubbo.common.extension.factory.AdaptiveExtensionFactory
spi=org.apache.dubbo.common.extension.factory.SpiExtensionFactory

ExtensionFactory類型的擴展,出了ExtensionFactory有兩個,一個 SpiExtensionFactory,另外一個是SpringExtensionFactory

SpiExtensionFactory 如何去搜索擴展呢? 我們去看代碼。

/**
 * SpiExtensionFactory
 */
public class SpiExtensionFactory implements ExtensionFactory {

    @Override
    public <T> T getExtension(Class<T> type, String name) {
        if (type.isInterface() && type.isAnnotationPresent(SPI.class)) {
            ExtensionLoader<T> loader = ExtensionLoader.getExtensionLoader(type);
            if (!loader.getSupportedExtensions().isEmpty()) {
                return loader.getAdaptiveExtension();
            }
        }
        return null;
    }

}

type是 接口,且帶有 @SPI註解的,獲取Adaptive擴展。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章