Dubbo—SPI及自适应扩展原理,区区一个SpringBoot问题就被干趴下了

本文详细探讨了Dubbo的SPI扩展机制和自适应扩展原理,从getExtensionClasses方法解析如何从配置文件加载扩展类,再到loadFile方法的关键步骤。文章指出,Dubbo通过缓存默认扩展实现类和读取配置文件实现扩展点的加载。自适应扩展机制确保在运行时根据需要懒加载扩展,避免资源浪费。此外,自适应扩展通过@Adaptive注解在类或方法上,实现动态创建适配类并调用相应扩展点的方法。Dubbo的自适应扩展类通过Compiler的适配器模式解决编译器选择问题,避免死循环。最后,文章预告将分析Dubbo的IOC功能。
摘要由CSDN通过智能技术生成

} catch (Throwable t) {
throw new IllegalStateException("Extension instance(name: " + name + ", class: " +
type + ") could not be instantiated: " + t.getMessage(), t);
}
}

关键点代码就在getExtensionClasses方法中,怎么从配置文件中加载扩展类的。而该方法主要是调用了loadExtensionClasses方法:

private Map<String, Class<?>> loadExtensionClasses() {
// 判断接口上是否标注有 @SPI注解,该注解的值就是默认使用的扩展类,
// 赋值给cachedDefaultName变量缓存起来
final SPI defaultAnnotation = type.getAnnotation(SPI.class);
if(defaultAnnotation != null) {
String value = defaultAnnotation.value();
if(value != null && (value = value.trim()).length() > 0) {
String[] names = NAME_SEPARATOR.split(value);
if(names.length > 1) {
throw new IllegalStateException("more than 1 default extension name on extension " + type.getName()

  • ": " + Arrays.toString(names));
    }
    if(names.length == 1) cachedDefaultNa 需要zi料+ 绿色徽【vip1024b】

me = names[0];
}
}

// 真正读取配置文件的方法
Map<String, Class<?>> extensionClasses = new HashMap

该方法主要是缓存当前扩展接口指定的默认扩展实现类(@SPI注解指定),并调用loadFile读取配置文件,从这里我们可以看到Dubbo默认是读取以下3个文件夹中的配置文件:

private static final String SERVICES_DIRECTORY = “META-INF/services/”;
private static final String DUBBO_DIRECTORY = “META-INF/dubbo/”;
private static final String DUBBO_INTERNAL_DIRECTORY = DUBBO_DIRECTORY + “internal/”;

然后是loadFile,该方法很长,不全部放上来了,这里提取关键的代码:

String fileName = dir + type.getName();

首先通过文件全路径找到对应的文件,并用BufferedReader一行行读取文件内容:

String name = null;
int i = line.indexOf(‘=’);
if (i > 0) {
// 配置文件中的键
name = line.substring(0, i).trim();
// 扩展点全类名
line = line.substring(i + 1).trim();
}
if (line.length() > 0) {
// 加载class,如果有些类的依赖jar包未导入,这里就会抛出异常(比如WebserviceProtocol)
Class<?> clazz = Class.forName(line, true, classLoader);
// 验证当前类型是否是扩展类的父类型
if (! type.isAssignableFrom(clazz)) {
throw new IllegalStateException("Error when load extension class(interface: " +
type + ", class line: " + clazz.getName() + "), class "

  • clazz.getName() + “is not subtype of interface.”);
    }
    // 扩展类是否标注了 @Adaptive 注解,表示为一个自定义的自适应扩展类
    // 如果是将其缓存到cachedAdaptiveClass
    if (clazz.isAnnotationPresent(Adaptive.class)) {
    if(cachedAdaptiveClass == null) {
    cachedAdaptiveClass = clazz;
    } else if (! cachedAdaptiveClass.equals(clazz)) {
    // 超过一个自定义的自适应扩展类就抛出异常
    throw new IllegalStateException("More than 1 adaptive class found: "
  • cachedAdaptiveClass.getClass().ge
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值