栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

@Extension、@SPI注解原理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

@Extension、@SPI注解原理

在dubbo源码中,涉及到一些dubbo自定义的注解,这篇笔记主要记录这些注解的原理和使用方式,了解了这些之后,便于我们对dubbo进行二次扩展

@SPI

dubbo的SPI机制,和Java原生的SPI机制相比,新增了name,可以指定某一个实现类对应的name,我们在使用的时候,可以根据name,获取自己想要使用的扩展类,如果在获取实现类时,指定name为true,默认返回的是@spi注解中指定的name对应的实现类
简单来说:@SPI注解中指定的value值,是当前接口默认的实现类,比如,下面的这个截图,就表示Protocol的默认实现类是DubboProtocol

这个在哪里可以体现呢?

com.alibaba.dubbo.common.extension.ExtensionLoader#loadExtensionClasses
在这个方法中,是加在指定文件目录下的文件的,其中会先根据type,获取到对应的@SPI注解,这里的type,就是对应的接口;所以,这里可以看到,会把@SPI注解中value对应的key,设置为CacheDefaultName这个变量中

com.alibaba.dubbo.common.extension.ExtensionLoader#getExtension
在这个方法中,是根据入参中的name,找到对应的实现类,比如:当前type是protocol,如果入参了dubbo,那就是要找key是dubbo的protocol实现类,通常是dubboProtocol

这里会看到,如果如此那的name是true,表示要获取的是默认的实现类
这里会看到,就是从CacheDefaultName中获取的

public T getDefaultExtension() {
   getExtensionClasses();
   if (null == cachedDefaultName || cachedDefaultName.length() == 0
           || "true".equals(cachedDefaultName)) {
       return null;
   }
   return getExtension(cachedDefaultName);
}

所以:@SPI注解,是加在接口上,表示该接口的默认实现类,在获取的时候,如果入参的name是true,会取默认的实现类

@Extension

通常在使用dubbo的SPI机制时,我们需要自己在文件中使用key = 全类名;这种格式来配置name;但是假如我们没有在文件中指定,那可以使用@Extension注解,加在实现类上,并指定key(这里的key就等同于文件中等号前面的key),因为在dubbo源码中,在解析文件的时候,如果没有指定name,会解析实现类是否有添加@Extension
这里需要注意的是:这个注解和@SPI注解两者之间,我认为是没有太大关系的,因为@SPI注解的value,是我们在指定name为true的时候,才会和@SPI注解有关系
而@Extension注解是key的一种设置方式
com.alibaba.dubbo.common.extension.ExtensionLoader#loadClass
在这个方法中,有一段代码

这个方法的上下文,简单介绍下,在dubbo源码中,会一次性加在type对应的所有实现类,会根据实现类,来区分,当前实现类是包装类?还是自适应扩展类?还是普通的实现类,如果是普通的实现,就会执行截图中的这个方法,在执行时,如果我们没有在文件中指定key = 实现类,那此时会判断实现类(这里的clazz已经是实现类了,因为dubbo会根据文件中的全类名,生成一个clazz)上是否有添加@Extension注解

private String findAnnotationName(Class clazz) {
    com.alibaba.dubbo.common.Extension extension = clazz.getAnnotation(com.alibaba.dubbo.common.Extension.class);
    if (extension == null) {
        String name = clazz.getSimpleName();
        if (name.endsWith(type.getSimpleName())) {
            name = name.substring(0, name.length() - type.getSimpleName().length());
        }
        return name.toLowerCase();
    }
    return extension.value();
}

所以,@Extension注解的含义是:如果我们在文件中,没有给实现类指定key,那就会去判断实现类是否有使用@Extension注解,有,就会使用注解对应的value来作为key

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1003980.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号