Dubbo源码解析 一、Dubbo的SPI机制

  SPI机制,即Service Provider Interface,服务提供接口。此机制的作用是更加方便、灵活的获取到接口实现方,而不是硬编码到代码中。比如在dubbo中通过Protocol的refer接口获取到最终执行的invoker,但是Protocol有多种实现,有DubboProtocol,也有RegistryProtocol,那么我该使用哪一种呢?这时候Dubbo的SPI机制要解决的问题。

一 、Dubbo中的扩展点与Adaptive:

  1、扩展点:

   可以认为是需要被扩展的接口,比如Protocol、RegistryFactory等等。

  2、Adaptive:

   能动态的获取到上述扩展点的实现类,此方法能根据特定的条件来获取到实现类,方法是通过调用方法时传入的URL来找到最终实现类的key,再从配置文件中根据key找到最终的实现类。

  具体如何找到我们会在接下来的源码解析中讲到其原理。

 

二、解析:

  下面以ReferenceConfig根据protocol获取到invoker举例。

  ReferenceConfig中protocol的Adaptive是这样来获取到的:

    private static final Protocol refprotocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();

可以看到是通过ExtensionLoader来获取到最终的Adaptive。我们一步一步来看。

    public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
        if (type == null)
            throw new IllegalArgumentException("Extension type == null");
        if (!type.isInterface()) {
            throw new IllegalArgumentException("Extension type(" + type + ") is not interface!");
        }
        // 扩展点接口必须有 @SPI 注解,否则会报错
        if (!withExtensionAnnotation(type)) {
            throw new IllegalArgumentException("Extension type(" + type +
                    ") is not extension, because WITHOUT @" + SPI.class.getSimpleName() + " Annotation!");
        }
        // 下面是一个单例模式,可以看到一个扩展点只能有一个对应的ExtensionLoader
        ExtensionLoader<T> loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
        if (loader == null) {
            EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader<T>(type));
            loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
        }
        return loader;
    }

下面看一下终点,获取到Adaptive实现类 ,可以看到Adaptive实现类也是单例。

    public T getAdaptiveExtension() {
        // 得到缓存的Adaptive实现类
        Object instance = cachedAdaptiveInstance.get();
        if (instance == null) {
            if (createAdaptiveInstanceError == null) {
                synchronized (cachedAdaptiveInstance) {
                    instance = cachedAdaptiveInstance.get();
                    if (instance == null) {
                        try {
                            // 如果为空,创建一个
                            instance = createAdaptiveExtension();
                            cachedAdaptiveInstance.set(instance);
                        } catch (Throwable t) {
                            createAdaptiveInstanceError = t;
                            throw new IllegalStateException("fail to create adaptive instance: " + t.toString(), t);
                        }
                    }
                }
            } else {
                throw new IllegalStateException("fail to create adaptive instance: " + createAdaptiveInstanceError.toString(), createAdaptiveInstanceError);
            }
        }

        return (T) instance;
    }

创建Adaptive的方法为直接生成扩展点 Adaptive实现的代码:


                
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值