Dubbo實(shí)例注入過程
更新時(shí)間:2025年11月08日 10:32:16 作者:hello_zzw
文章主要介紹了Dubbo框架中ExtensionLoader類的創(chuàng)建、初始化、后處理和注入擴(kuò)展點(diǎn)的詳細(xì)過程,特別是通過AdaptiveExtensionInjector進(jìn)行注入的部分
Dubbo實(shí)例注入
org.apache.dubbo.common.extension.ExtensionLoader#createExtension
/**
* 根據(jù)指定擴(kuò)展點(diǎn)名稱去創(chuàng)建擴(kuò)展點(diǎn)實(shí)例對(duì)象
*/
@SuppressWarnings("unchecked")
private T createExtension(String name, boolean wrap) {
// getExtensionClasses 為當(dāng)前 SPI 接口的所有實(shí)現(xiàn)類的類信息集合
// 通過指定的擴(kuò)展點(diǎn)名稱 name 來獲取與之對(duì)應(yīng)的實(shí)現(xiàn)類類信息
Class<?> clazz = getExtensionClasses().get(name);
// 若找不到對(duì)應(yīng)的擴(kuò)展點(diǎn),或者當(dāng)初加載時(shí)擴(kuò)展點(diǎn)有重復(fù)名稱拋出異常
if (clazz == null || unacceptableExceptions.contains(name)) {
throw findException(name);
}
try {
// extensionInstances 為當(dāng)前 SPI 接口已經(jīng)經(jīng)過實(shí)例化的實(shí)例對(duì)象集合
// 然后通過指定的擴(kuò)展點(diǎn)名稱看看有沒有與之對(duì)應(yīng)的已經(jīng)曾經(jīng)創(chuàng)建好的實(shí)例對(duì)象
T instance = (T) extensionInstances.get(clazz);
// 若找不到,說明沒有緩存,從而則說明該擴(kuò)展點(diǎn)名稱也是首次使用
if (instance == null) {
// 通過并發(fā) Map 的 putIfAbsent 方法以線程安全的形式,
// 來保證該實(shí)現(xiàn)類只會(huì)創(chuàng)建一個(gè)實(shí)例對(duì)象,實(shí)例對(duì)象是反射方式創(chuàng)建出來的
extensionInstances.putIfAbsent(clazz, createExtensionInstance(clazz));
// 獲取剛剛創(chuàng)建的實(shí)例對(duì)象
instance = (T) extensionInstances.get(clazz);
// 初始化前置處理,即將原始的對(duì)象進(jìn)行前置包裝等處理
instance = postProcessBeforeInitialization(instance, name);
// 擴(kuò)展點(diǎn)注入
injectExtension(instance);
// 初始化后置處理,即將已初始化實(shí)例化注入的對(duì)象進(jìn)行后置包裝等處理
instance = postProcessAfterInitialization(instance, name);
}
// wrap 是否需要進(jìn)行裝飾器包裝
if (wrap) {
List<Class<?>> wrapperClassesList = new ArrayList<>();
// 看看是否有裝飾器包裝類,即實(shí)現(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)裝飾器包裝類,進(jìn)行層層套娃包裝
for (Class<?> wrapperClass : wrapperClassesList) {
// 裝飾器類上是否 Wrapper 注解
Wrapper wrapper = wrapperClass.getAnnotation(Wrapper.class);
// 1. 沒有 wrapper 注解,需要進(jìn)行包裝
// 2. wrapper 中的 matches 字段值為空沒有內(nèi)容,需要進(jìn)行包裝
// 3. wrapper 中的 matches 字段值不為空并包含入?yún)?name 值,并且 mismatches 字段值不包含 name 值,需要進(jìn)行包裝
// 4. 其他情況,可能就是瞎寫亂配,導(dǎo)致無法進(jìn)行包裝之類的
boolean match = (wrapper == null)
|| ((ArrayUtils.isEmpty(wrapper.matches())
|| ArrayUtils.contains(wrapper.matches(), name))
&& !ArrayUtils.contains(wrapper.mismatches(), name));
// 如果匹配成功,則進(jìn)行包裝
if (match) {
// 針對(duì)包裝的類再次進(jìn)行實(shí)例注入
instance = injectExtension(
(T) wrapperClass.getConstructor(type).newInstance(instance));
// 針對(duì)包裝類,同樣進(jìn)行后置處理
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 {
// 存在擴(kuò)展后處理器時(shí),循環(huán)處理所有的后置處理器
if (extensionPostProcessors != null) {
for (ExtensionPostProcessor processor : extensionPostProcessors) {
// 循環(huán)調(diào)用所有后置處理器中的初始化前置方法
instance = (T) processor.postProcessBeforeInitialization(instance, name);
}
}
// 返回處理后的對(duì)象
return instance;
}
/**
* 初始化后置處理方法
*/
@SuppressWarnings("unchecked")
private T postProcessAfterInitialization(T instance, String name) throws Exception {
// 如果實(shí)例實(shí)現(xiàn)了ExtensionAccessorAware,自動(dòng)注入extensionDirector作為擴(kuò)展訪問器
if (instance instanceof ExtensionAccessorAware) {
((ExtensionAccessorAware) instance).setExtensionAccessor(extensionDirector);
}
// 存在擴(kuò)展后處理器時(shí),循環(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
/**
* 注入擴(kuò)展點(diǎn)的方法
*/
private T injectExtension(T instance) {
if (injector == null) {
return instance;
}
try {
// 循環(huán)處理實(shí)例對(duì)象的所有public方法
for (Method method : instance.getClass().getMethods()) {
// 只處理set開頭,public修飾,只有一個(gè)參數(shù)的方法
if (!isSetter(method)) {
continue;
}
// 不處理帶有DisableInject注解的方法
if (method.isAnnotationPresent(DisableInject.class)) {
continue;
}
// 過濾掉實(shí)現(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;
}
}
// 獲取第一個(gè)參數(shù)
Class<?> pt = method.getParameterTypes()[0];
// 基礎(chǔ)類型不做處理
if (ReflectUtils.isPrimitives(pt)) {
continue;
}
try {
// 獲取set方法對(duì)應(yīng)的屬性
// set方法大于三個(gè)分字符時(shí),去除set后抽字母小寫
// 小于等于三個(gè)字符時(shí),返回""
String property = getSetterProperty(method);
// 根據(jù)參數(shù)類型、屬性名稱 從容器中獲取對(duì)應(yīng)的實(shí)例對(duì)象
Object object = injector.getInstance(pt, property);
if (object != null) {
// 獲取到實(shí)例對(duì)象時(shí),使用set方法設(shè)置到對(duì)象中
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 {
// 獲取【擴(kuò)展點(diǎn)注入器】的加載器
ExtensionLoader<ExtensionInjector> loader = extensionAccessor.getExtensionLoader(ExtensionInjector.class);
injectors = loader.getSupportedExtensions().stream()
// 從加載器中拿出所有的可被使用的注冊(cè)器實(shí)現(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)所有的擴(kuò)展點(diǎn)注入器
return injectors.stream()
// 從容器中根據(jù)類型加名字獲取實(shí)例對(duì)象
.map(injector -> injector.getInstance(type, name))
.filter(Objects::nonNull)
// 獲取到第一個(gè)就結(jié)束
.findFirst()
.orElse(null);
}
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
springboot中實(shí)現(xiàn)上傳文件的功能簡(jiǎn)單示例
這篇文章主要給大家介紹了關(guān)于springboot中實(shí)現(xiàn)上傳文件功能的相關(guān)資料,在Spring Boot中實(shí)現(xiàn)文件上傳下載功能相對(duì)簡(jiǎn)單,文中給出了代碼示例,需要的朋友可以參考下2023-09-09
關(guān)于使用Lambda表達(dá)式簡(jiǎn)化Comparator的使用問題
這篇文章主要介紹了關(guān)于使用Lambda表達(dá)式簡(jiǎn)化Comparator的使用問題,文中圖文講解了Comparator對(duì)象的方法,需要的朋友可以參考下2023-04-04
mybatis?plus實(shí)現(xiàn)分頁邏輯刪除
這篇文章主要為大家介紹了mybatis?plus實(shí)現(xiàn)分頁邏輯刪除的方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05
Spring?Boot?結(jié)合?WxJava?實(shí)現(xiàn)文章上傳微信公眾號(hào)草稿箱與群發(fā)
本文將詳細(xì)介紹如何使用SpringBoot框架結(jié)合WxJava開發(fā)工具包,實(shí)現(xiàn)文章上傳到微信公眾號(hào)草稿箱以及群發(fā)功能,感興趣的朋友一起看看吧2025-07-07
基于jni調(diào)用時(shí),jvm報(bào)錯(cuò)問題的深入分析
本篇文章是對(duì)jni調(diào)用時(shí),jvm的報(bào)錯(cuò)問題進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05

