欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Dubbo實例注入過程

 更新時間:2025年11月08日 10:32:16   作者:hello_zzw  
文章主要介紹了Dubbo框架中ExtensionLoader類的創(chuàng)建、初始化、后處理和注入擴展點的詳細(xì)過程,特別是通過AdaptiveExtensionInjector進行注入的部分

Dubbo實例注入

org.apache.dubbo.common.extension.ExtensionLoader#createExtension

/**
 * 根據(jù)指定擴展點名稱去創(chuàng)建擴展點實例對象
 */
@SuppressWarnings("unchecked")
private T createExtension(String name, boolean wrap) {
    // getExtensionClasses 為當(dāng)前 SPI 接口的所有實現(xiàn)類的類信息集合
    // 通過指定的擴展點名稱 name 來獲取與之對應(yīng)的實現(xiàn)類類信息
    Class<?> clazz = getExtensionClasses().get(name);
    // 若找不到對應(yīng)的擴展點,或者當(dāng)初加載時擴展點有重復(fù)名稱拋出異常
    if (clazz == null || unacceptableExceptions.contains(name)) {
        throw findException(name);
    }
    try {
        // extensionInstances 為當(dāng)前 SPI 接口已經(jīng)經(jīng)過實例化的實例對象集合
        // 然后通過指定的擴展點名稱看看有沒有與之對應(yīng)的已經(jīng)曾經(jīng)創(chuàng)建好的實例對象
        T instance = (T) extensionInstances.get(clazz);
        // 若找不到,說明沒有緩存,從而則說明該擴展點名稱也是首次使用
        if (instance == null) {
            // 通過并發(fā) Map 的 putIfAbsent 方法以線程安全的形式,
            // 來保證該實現(xiàn)類只會創(chuàng)建一個實例對象,實例對象是反射方式創(chuàng)建出來的
            extensionInstances.putIfAbsent(clazz, createExtensionInstance(clazz));
            // 獲取剛剛創(chuàng)建的實例對象
            instance = (T) extensionInstances.get(clazz);
            // 初始化前置處理,即將原始的對象進行前置包裝等處理
            instance = postProcessBeforeInitialization(instance, name);
            // 擴展點注入
            injectExtension(instance);
            // 初始化后置處理,即將已初始化實例化注入的對象進行后置包裝等處理
            instance = postProcessAfterInitialization(instance, name);
        }

        // wrap 是否需要進行裝飾器包裝
        if (wrap) {
            List<Class<?>> wrapperClassesList = new ArrayList<>();
            // 看看是否有裝飾器包裝類,即實現(xiàn)類中單一參數(shù)的構(gòu)造方法是不是 SPI 接口
            if (cachedWrapperClasses != null) {
                wrapperClassesList.addAll(cachedWrapperClasses);
                wrapperClassesList.sort(WrapperComparator.COMPARATOR);
                Collections.reverse(wrapperClassesList);
            }

            if (CollectionUtils.isNotEmpty(wrapperClassesList)) {
                // 循環(huán)裝飾器包裝類,進行層層套娃包裝
                for (Class<?> wrapperClass : wrapperClassesList) {
                    // 裝飾器類上是否 Wrapper 注解
                    Wrapper wrapper = wrapperClass.getAnnotation(Wrapper.class);
                    // 1. 沒有 wrapper 注解,需要進行包裝
                    // 2. wrapper 中的 matches 字段值為空沒有內(nèi)容,需要進行包裝
                    // 3. wrapper 中的 matches 字段值不為空并包含入?yún)?name 值,并且 mismatches 字段值不包含 name 值,需要進行包裝
                    // 4. 其他情況,可能就是瞎寫亂配,導(dǎo)致無法進行包裝之類的
                    boolean match = (wrapper == null)
                            || ((ArrayUtils.isEmpty(wrapper.matches())
                                            || ArrayUtils.contains(wrapper.matches(), name))
                                    && !ArrayUtils.contains(wrapper.mismatches(), name));
                    // 如果匹配成功,則進行包裝
                    if (match) {
                        // 針對包裝的類再次進行實例注入
                        instance = injectExtension(
                                (T) wrapperClass.getConstructor(type).newInstance(instance));
                        // 針對包裝類,同樣進行后置處理
                        instance = postProcessAfterInitialization(instance, name);
                    }
                }
            }
        }

        // Warning: After an instance of Lifecycle is wrapped by cachedWrapperClasses, it may not still be Lifecycle
        // instance, this application may not invoke the lifecycle.initialize hook.
        initExtension(instance);
        return instance;
    } catch (Throwable t) {
        throw new IllegalStateException(
                "Extension instance (name: " + name + ", class: " + type + ") couldn't be instantiated: "
                        + t.getMessage(),
                t);
    }
}

org.apache.dubbo.common.extension.ExtensionLoader#postProcessBeforeInitialization

/**
 * 初始化前置處理方法
 */
@SuppressWarnings("unchecked")
private T postProcessBeforeInitialization(T instance, String name) throws Exception {
    // 存在擴展后處理器時,循環(huán)處理所有的后置處理器
    if (extensionPostProcessors != null) {
        for (ExtensionPostProcessor processor : extensionPostProcessors) {
            // 循環(huán)調(diào)用所有后置處理器中的初始化前置方法
            instance = (T) processor.postProcessBeforeInitialization(instance, name);
        }
    }
    // 返回處理后的對象
    return instance;
}
/**
 * 初始化后置處理方法
 */
@SuppressWarnings("unchecked")
private T postProcessAfterInitialization(T instance, String name) throws Exception {
    // 如果實例實現(xiàn)了ExtensionAccessorAware,自動注入extensionDirector作為擴展訪問器
    if (instance instanceof ExtensionAccessorAware) {
        ((ExtensionAccessorAware) instance).setExtensionAccessor(extensionDirector);
    }
    // 存在擴展后處理器時,循環(huán)處理所有的后置處理器
    if (extensionPostProcessors != null) {
        for (ExtensionPostProcessor processor : extensionPostProcessors) {
            // 循環(huán)調(diào)用所有后置處理器中的初始化后置方法
            instance = (T) processor.postProcessAfterInitialization(instance, name);
        }
    }
    return instance;
}

org.apache.dubbo.common.extension.ExtensionLoader#injectExtension

/**
 * 注入擴展點的方法
 */
private T injectExtension(T instance) {
    if (injector == null) {
        return instance;
    }

    try {
        // 循環(huán)處理實例對象的所有public方法
        for (Method method : instance.getClass().getMethods()) {
            // 只處理set開頭,public修飾,只有一個參數(shù)的方法
            if (!isSetter(method)) {
                continue;
            }
            // 不處理帶有DisableInject注解的方法
            if (method.isAnnotationPresent(DisableInject.class)) {
                continue;
            }

            // 過濾掉實現(xiàn)自ScopeModelAware的方法
            if (method.getDeclaringClass() == ScopeModelAware.class) {
                continue;
            }
            // 過濾掉 ScopeModelAware、ExtensionAccessorAware 的方法
            if (instance instanceof ScopeModelAware || instance instanceof ExtensionAccessorAware) {
                if (ignoredInjectMethodsDesc.contains(ReflectUtils.getDesc(method))) {
                    continue;
                }
            }

            // 獲取第一個參數(shù)
            Class<?> pt = method.getParameterTypes()[0];
            // 基礎(chǔ)類型不做處理
            if (ReflectUtils.isPrimitives(pt)) {
                continue;
            }

            try {
                // 獲取set方法對應(yīng)的屬性
                // set方法大于三個分字符時,去除set后抽字母小寫
                // 小于等于三個字符時,返回""
                String property = getSetterProperty(method);
                // 根據(jù)參數(shù)類型、屬性名稱 從容器中獲取對應(yīng)的實例對象
                Object object = injector.getInstance(pt, property);
                if (object != null) {
                    // 獲取到實例對象時,使用set方法設(shè)置到對象中
                    method.invoke(instance, object);
                }
            } catch (Exception e) {
                logger.error(
                        COMMON_ERROR_LOAD_EXTENSION,
                        "",
                        "",
                        "Failed to inject via method " + method.getName() + " of interface " + type.getName() + ": "
                                + e.getMessage(),
                        e);
            }
        }
    } catch (Exception e) {
        logger.error(COMMON_ERROR_LOAD_EXTENSION, "", "", e.getMessage(), e);
    }
    return instance;
}

org.apache.dubbo.common.extension.inject.AdaptiveExtensionInjector

@Override
public void initialize() throws IllegalStateException {
    // 獲取【擴展點注入器】的加載器
    ExtensionLoader<ExtensionInjector> loader = extensionAccessor.getExtensionLoader(ExtensionInjector.class);
    injectors = loader.getSupportedExtensions().stream()
            // 從加載器中拿出所有的可被使用的注冊器實現(xiàn)類
            .map(loader::getExtension)
            // 包裝在不可變集合中
            .collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
}

@Override
public <T> T getInstance(final Class<T> type, final String name) {
    // 循環(huán)所有的擴展點注入器
    return injectors.stream()
            // 從容器中根據(jù)類型加名字獲取實例對象
            .map(injector -> injector.getInstance(type, name))
            .filter(Objects::nonNull)
            // 獲取到第一個就結(jié)束
            .findFirst()
            .orElse(null);
}

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論