Dubbo系列讲解之扩展点实现原理分析【2万字分享】

本文深入探讨了Dubbo的扩展点实现原理,包括从缓存获取扩展点、创建自适应扩展、加载扩展类、扫描加载策略、依赖注入等关键步骤。详细分析了如何动态生成并编译自适应扩展类,以及ExtensionFactory的自适应扩展点AdaptiveExtensionFactory的实现。文章结尾分享了成为优秀架构师的心得体会。
摘要由CSDN通过智能技术生成

} catch (Throwable t) {

// 异常信息缓存起来,下一次进来时如果发现是创建实例是出现异常,就直接抛出异常。这里的设计应该是当扩展点创建异常时避免多次执行创建流程的优化

createAdaptiveInstanceError = t;

throw new IllegalStateException("Failed to create adaptive instance: " + t.toString(), t);

}

}

}

}

return (T) instance;

}

该方法主要做了以下几件事

  • 从缓存cachedAdaptiveInstance中获取扩展点实现,存在该扩展点对象,则直接返回该实例。cachedAdaptiveInstance是一个Holder对象,主要用于缓存该扩展点的实现的具体实例,因为这里只会返回一个自适应扩展点的实现(有多个实现类标注了则按文件定义顺序取最后一个),实现对于每个``ExtensionLoader`来说,自适应扩展点是单例的。

  • 如果扩展点实现不存在,调用createAdaptiveExtension()创建一个具体的实现,并将该实例set到cachedAdaptiveInstance中缓存起来。

创建扩展点实现的具体流程是在createAdaptiveExtension方法中

private Class<?> getAdaptiveExtensionClass() {

getExtensionClasses();

if (cachedAdaptiveClass != null) {

return cachedAdaptiveClass;

}

return cachedAdaptiveClass = createAdaptiveExtensionClass();

}

该方法主要做了以下几件事

  • 调用getExtensionClasses(),顾名思义,该方法主要是获取扩展点的所有实现的.class对象。

  • 如果缓存的cachedAdaptiveClass 对象不为null,直接返回。(cachedAdaptiveClass是一个class对象,用于保存该扩展点的自适应扩展点的实现,即是该扩展点的实现类中存在有将@Adaptive标注在类上的默认自适应扩展点)

  • 如果为缓存有cachedAdaptiveClass对象,则调用createAdaptiveExtensionClass创建一个cachedAdaptiveClass,并复制给cachedAdaptiveClass

接下来首先进入getExtensionClasses()方法

private Map<String, Class<?>> getExtensionClasses() {

Map<String, Class<?>> classes = cachedClasses.get();

if (classes == null) {

synchronized (cachedClasses) {

classes = cachedClasses.get();

if (classes == null) {

classes = loadExtensionClasses();

cachedClasses.set(classes);

}

}

}

return classes;

}

该方法首先会从cachedClasses(cachedClasses也是一个holder,用于存储每个扩展点的所有扩展实现的map集合)获取该.class对象,存在则直接返回,否则调用loadExtensionClasses方法加载扩展点的classs,将加载到的classes存到cachedClasses中。

接下来进入loadExtensionClasses

private Map<String, Class<?>> loadExtensionClasses() {

cacheDefaultExtensionName();

Map<String, Class<?>> extensionClasses = new HashMap<>();

for (LoadingStrategy strategy : strategies) {

// 扫描每个加载策略目录中的扩展点实现

loadDirectory(extensionClasses, strategy.directory(), type.getName(), strategy.preferExtensionClassLoader(), strategy.overridden(), strategy.excludedPackages());

// 对alibaba的践行兼容

loadDirectory(extensionClasses, strategy.directory(), type.getName().replace(“org.apache”, “com.alibaba”), strategy.preferExtensionClassLoader(), strategy.overridden(), strategy.excludedPackages());

}

return extensionClasses;

}

首先调用cacheDefaultExtensionName()方法。再给接口标注@SPI的时候,可以给个默认的value值,表示指定的默认的扩展点实现,如@S

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值