dubbo之SPI自适应扩展机制

栏目: 后端 · 发布时间: 5年前

内容简介:在 Dubbo 中,很多拓展都是通过 SPI 机制进行加载的,比如 Protocol、Cluster、LoadBalance 等。有时,为了很好的理解,下面结合实例进行分析,在Dubbbo暴露服务中,ServiceConfig类中doExportUrlsFor1Protocol方法中有如下这样一条语句:接下来咱们就根据这条语句进行深入分析Dubbo SPI自适应扩展机制。

1、背景

在 Dubbo 中,很多拓展都是通过 SPI 机制进行加载的,比如 Protocol、Cluster、LoadBalance 等。有时, 有些拓展并不想在框架启动阶段被加载,而是希望在拓展方法被调用时,根据运行时参数进行加载 。这听起来有些矛盾。拓展未被加载,那么拓展方法就无法被调用(静态方法除外)。拓展方法未被调用,拓展就无法被加载。对于这个矛盾的问题,Dubbo 通过自适应拓展机制很好的解决了。自适应拓展机制的实现逻辑比较复杂,首先 Dubbo 会为拓展接口生成具有代理功能的代码。然后通过 javassist 或 jdk 编译这段代码,得到 Class 类。最后再通过反射创建代理类,整个过程比较复杂。

2、原理

为了很好的理解,下面结合实例进行分析,在Dubbbo暴露服务中,ServiceConfig类中doExportUrlsFor1Protocol方法中有如下这样一条语句:

Exporter<?> exporter = protocol.export(wrapperInvoker);

接下来咱们就根据这条语句进行深入分析Dubbo SPI自适应扩展机制。

根据源码查询得知,protocol对象是通过以下语句创建:

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

根据上篇文章,咱们得知getExtensionLoader只是获取ExtensionLoader对象,所以自适应扩展的核心在getAdaptiveExtension()方法中:

public T getAdaptiveExtension() {
        // 缓存获取实例对象
        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;
    }

在getAdaptiveExtension方法中先从缓存中获取,缓存中不存在在创建实例,并存入缓存中,逻辑比较简单,咱们在来分析createAdaptiveExtension方法:

private T createAdaptiveExtension() {
        try {
            return injectExtension((T) getAdaptiveExtensionClass().newInstance());
        } catch (Exception e) {
            throw new IllegalStateException("Can not create adaptive extension " + type + ", cause: " + e.getMessage(), e);
        }
    }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Everything Store

The Everything Store

Brad Stone / Little, Brown and Company / 2013-10-22 / USD 28.00

The definitive story of Amazon.com, one of the most successful companies in the world, and of its driven, brilliant founder, Jeff Bezos. Amazon.com started off delivering books through the mail. Bu......一起来看看 《The Everything Store》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

SHA 加密
SHA 加密

SHA 加密工具