您当前的位置: 首页 >  dubbo

Charge8

暂无认证

  • 6浏览

    0关注

    447博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Dubbo SPI机制使用

Charge8 发布时间:2022-07-10 15:31:05 ,浏览量:6

Java SPI机制博客传送门:https://blog.csdn.net/qq_42402854/article/details/125705159 注意:JDK SPI会一次性实例化扩展点的所有实现。

Dubbo没有使用JDK的SPI机制,而是自己实现的一套SPI机制。在Dubbo的源码中,很多地方会存在下面这样的三种代码:

//获取自适应扩展点
ExtensionLoader.getExtensionLoader(xxx.class).getAdaptiveExtension();
//获取指定名称的扩展点
ExtensionLoader.getExtensionLoader(xxx.class).getExtension(name);
//激活扩展点
ExtensionLoader.getExtensionLoader(xxx.class).getActivateExtension(url, key);

在Dubbo中,SPI贯穿整个Dubbo的核心,所以理解Dubbo中的SPI对于理解Dubbo的原理有着至关重要的作用。

  • 在Java中,通过 java.util.ServiceLoader 来发现动态加载具体的实现类到JVM中。
  • 在Spring中,SpringFactoriesLoader这个类,它也是一种SPI机制。
  • 在Dubbo中,ExtensionLoader这个类,它也是一种SPI机制。
一、Dubbo SPI机制使用 1、Dubbo的 SPI机制

Dubbo的 SPI机制:来自《Apache Dubbo与实战》一书中截图。 在这里插入图片描述 在这里插入图片描述

1.1 扩展点注解 1.1.1 @SPI注解

@SPI注解可以使用在类,接口和枚举上。

主要作用就是标记这个接口是一个 Dubbo SPI接口,即一个扩展点。 value,表示可以设置默认的实现类

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface SPI {

    /**
     * default extension name
     */
    String value() default "";

}
1.1.2 @Adaptive注解

在这里插入图片描述 @Adaptive注解 可以标记在类、接口、枚举类和方法上。

自适应扩展点的知识,表示在运行时使用那个实现类。 当该注解使用在类上时,只能有一个实现类上可以加 @Adaptive注解,如果多个实现类都有该注解会抛出异常。

包装类等其他的自行了解。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Adaptive {
    String[] value() default {};
}
1.1.3 @Acticate注解

@Acticate注解 可以标记在类、接口、枚举类和方法上。

默认自动激活,主要使用在多个扩展点实现、还可以根据不同条件被激活的场景中。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Activate {
    String[] group() default {};

    String[] value() default {};

    String[] before() default {};

    String[] after() default {};

    int order() default 0;
}
2、获取Protocol扩展点
    public static void main(String[] args) {
        ExtensionLoader extensionLoader = ExtensionLoader.getExtensionLoader(Protocol.class);

        Protocol dubbo = extensionLoader.getExtension("dubbo");
        System.out.println("dubbo 指定名称的扩展点:" + dubbo);
        System.out.println("dubbo 自适应扩展点:" + extensionLoader.getAdaptiveExtension());
        System.out.println("dubbo 默认扩展点协议:" + extensionLoader.getDefaultExtension());
        System.out.println("dubbo 获取所有扩展点协议:" + extensionLoader.getSupportedExtensions());

    }

在这里插入图片描述

Protocol接口源码如下: 在这里插入图片描述

二、自定义扩展点

这里写个 demo 感受一下 dubbo的SPI机制。

1、定义扩展点和实现类 1.1 扩展点

@SPI注解:value,表示设置默认的实现类

@SPI("MyLog")
public interface MyLog {

    void debug();
}
1.2 实现类

这里定义三个实现类。

@Activate
public class MyLog4j implements MyLog{

    @Override
    public void debug() {
        System.out.println("==========dubbo MyLog4j");
    }
}

@Activate
public class MyLogback implements MyLog{
    @Override
    public void debug() {
        System.out.println("==========dubbo MyLogback");
    }
}

@Adaptive
//@Activate
public class MyAdaptiveLog implements MyLog{

    @Override
    public void debug() {
        System.out.println("==========dubbo MyAdaptiveLog");
    }
}
2、创建配置文件

在项目resources目录下新建一个 META-INF/dubbo/文件夹。

  • 在 META-INF/dubbo/目录下,创建一个文件,文件名为该SPI接口的全限定名
  • 文件内容是 key=具体实现类的全限定名,如果有多个,则用分行符分隔。

在这里插入图片描述

3、测试,加载实现类

在 代码中通过 org.apache.dubbo.common.extension.ExtensionLoader来加载具体的实现类。

    @Test
    public void test() {
        ExtensionLoader extensionLoader = ExtensionLoader.getExtensionLoader(MyLog.class);

        MyLog myLogback = extensionLoader.getExtension("myLogback");
        System.out.println("MyLog 指定名称的扩展点:" + myLogback);
        myLogback.debug();

        // 获取实现了@Adaptive注解的实现类
        System.out.println("MyLog 自适应扩展点:" + extensionLoader.getAdaptiveExtension());
        System.out.println("MyLog 默认扩展点协议:" + extensionLoader.getDefaultExtension());
        System.out.println("MyLog 获取所有扩展点:" + extensionLoader.getSupportedExtensions());
    }

在这里插入图片描述

– 求知若饥,虚心若愚。

关注
打赏
1664721914
查看更多评论
立即登录/注册

微信扫码登录

0.0398s