JDK标准中SPI机制的一个问题就是其一次性实例化扩展点所有实现,如果有扩展实现初始化很耗时,但如果没用上也加载,会很浪费资源;扩展点加载失败,其他扩展点都用不了了。Dubbo是如何解决该问题动态的选择具体的扩展点呢?使用@Adaptive。

  Dubbo中的Adaptive功能,主要解决的问题是如何动态的选择具体的扩展点。通过getAdaptiveExtension同一对知道接口对于的所有扩展点进行封装,同时通过URL的方式对扩展点来进行动态选择(dubbo中所有的注册信息都是通过URL的形式进行处理的。)

  查看@Adaptive注解源码及其注释,如下:

    

       

  通过上面注释分析自适应功能执行流程如下:

  1、如果不使用@Adaptive,使用@SPI标记的所有扩展均被默认加载;

  2、使用@Adaptive的扩展被选择加载,可以加载整个扩展点也可以加载该扩展点中某个功能点(根据URL和@Adaptive中参数同时决定)。

  下面具体应用@Adaptive验证上述功能:

    1、创建接口

      增加传入URL参数的方法: 

    2、创建实现类

       实现有参数URL的方法:

       

    3、编写主程序

      

    红框部分为自适应加载扩展点比默认加载所有扩展需要明确注意的:1)URL参数;2)明确地使用getAdaptiveE'xtension加载自适应扩展。

  在第一步接口中,需要增加@Adaptive。下面验证不直接添加,而是通过测试验证注解功能一步步添加。增加配置文件内容    

    

  首先测试@Adaptive无参固定,@SPI与URL之间参数变化的场景,如下:

    1)修改@SPI注解为@SPI("hello")或者其他任意字符,执行DubboSPI机制二之Dubbo中SPI初体验 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中的主程序

       

      执行结果:

        

      对于非自适应的加载,@SPI有无指定默认加载都无效,默认加载所有。

    2)同上,但是执行此文中主程序(使用了getAdaptiveExtension方法,以下测试均使用)。结果如下:

      

      失败:提示在此扩展中没有自适应的方法,进而拒绝创建自适应实例。

    3)方法上增加自适应标签@Adaptive

        

      执行主程序,结果如下:

        

      URL中有dog,执行的时候找到的是扩展名为dog的扩展实现。如果改为human呢?应该是hello 加url了。验证确实如此:

        

      如果URL中扩展名为空呢?

        

        

      失败:提示无name为hello的扩展实现。配置文件中确实没有名为hello的扩展实现。说明对于URL中没有扩展名的自适应,默认使用@SPI中指定的扩展实现。

    4)提供默认扩展名为human

        

      执行结果为:

        

      如果无默认扩展名呢?

        

      执行结果为:

        

      失败:提示扩展名为null

  其次测试测试@Adaptive有参数时,其与URL是如何共同控制自适应扩展点加载:

    1)此案例@Adaptive设置参数hello.service:

        

      如果URL中无扩展名,执行主程序结果:    

        

      可以看到如果使用了正确参数XX的@Adptive,如果URL中使用没有为XX赋值,使用@SPI指定扩展实现。

    2)如果URL中扩展名为dog,执行主程序及结果:

        

      说明使用URL中提供扩展名扩展实现。

  综合上述@SPI,@Adaptive, URL三者配合使用如下:

  URL中提供扩展名:

    1)如果没有使用getAdaptiveExtension方法,有无@Adaptive无所谓,@SPI有无扩展名也无影响,直接加载所有扩展实现;

    2)如果使用getAdaptiveExtension方法,没有@Adaptive参数,交易失败;提供@Adaptiveh参数,加载URL中符合接口参数的扩展实现;如果无符合接口参数的,加载@SPI中指定扩展实现。

  URL中无扩展名信息:无论@Adaptive中是否提供参数,均加载@SPI中指定扩展实现。

  对于@Adaptive中参数,此例中为什么是hello.service?这个可以看最开始注释部分其默认参数名规则:

    

      

Dubbo SPI机制之三Adaptive自适应功能的更多相关文章

  1. 【Dubbo源码阅读系列】之 Dubbo SPI 机制

    最近抽空开始了 Dubbo 源码的阅读之旅,希望可以通过写文章的方式记录和分享自己对 Dubbo 的理解.如果在本文出现一些纰漏或者错误之处,也希望大家不吝指出. Dubbo SPI 介绍 Java ...

  2. Dubbo SPI 机制源码分析(基于2.7.7)

    Dubbo SPI 机制涉及到 @SPI.@Adaptive.@Activate 三个注解,ExtensionLoader 作为 Dubbo SPI 机制的核心负责加载和管理扩展点及其实现.本文以 E ...

  3. Dubbo SPI机制之一JDK中的SPI

    首先简单阐述下什么是SPI:SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制.目前有不少框架用它来做服务的扩展发现,简单来说,就是一种动态 ...

  4. dubbo SPI机制

    源码分析: /** * 获取扩展类 */ @SuppressWarnings("unchecked") public T getExtension(String name) { i ...

  5. Dubbo 源码分析 - SPI 机制

    1.简介 SPI 全称为 Service Provider Interface,是 Java 提供的一种服务发现机制.SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加 ...

  6. 面试常问的dubbo的spi机制到底是什么?

    前言 dubbo是一款微服务开发框架,它提供了 RPC通信 与 微服务治理 两大关键能力.作为spring cloud alibaba体系中重要的一部分,随着spring cloud alibaba在 ...

  7. SPI 机制-插件化扩展功能

    SPI(Service Provider Interfaces),中文直译服务提供者接口,一种服务发现机制.可能很多人都不太熟悉这个机制,但是平常或多或少都用到了这个机制,比如我们使用 JDBC 连接 ...

  8. Dubbo SPI源码解析①

    目录 0.Java SPI示例 1.Dubbo SPI示例 2.Dubbo SPI源码分析 ​ SPI英文全称为Service Provider Interface.它的作用就是将接口实现类的全限定名 ...

  9. Dubbo源码学习之-Adaptive自适应扩展

    前言 最近三周基本处于9-10-6与9-10-7之间,忙碌的节奏机会丢失了自己.除了之前干施工的那段经历,只看参加软件开发以来,前段时间是最繁忙的了.忙的原因,不是要完成的工作量大,而是各种环境问题, ...

随机推荐

  1. 利用Word2010制作流程图

    利用Word2010制作流程图 原文链接:https://www.toutiao.com/i6483034968225235469/ 一.页面和段落的设置 启动Word2010,打开一个空白文档,并切 ...

  2. element ui 动态菜单解决方案集锦

    1.<分享一个VUE Element-UI 的多级菜单动态渲染的组件> 2.<饿了么组件库,element-ui开发精美的后台管理系统系列之(一)开发伸缩菜单> 3.<V ...

  3. javascript实现数字整数位每三位一个逗号分隔

    Number(1234567).toLocaleString(); //结果"1,234,567" Number(123456789).toLocaleString()//结果&q ...

  4. 封装OCX

    封装OCX的办法有2种: 1. 使用C++的MFC activex项目生成OCX 2. 使用C#的用户控件生成OCX(.net core好像不支持) 注意:以管理员身份运行Visual Studio ...

  5. nRF24L01无线模块笔记

    nRF24L01模块 官网链接: https://www.nordicsemi.com/Products/nRF24-series 常见的无线收发模块, 工作在2.4GHz频段, 适合近距离遥控和数据 ...

  6. 【代码分享】用redis+lua实现多个集合取交集并过滤,类似于: select key from set2 where key in (select key from set1) and value>=xxx

    redis中的zset结构可以看成一个个包含数值的集合,或者认为是一个关系数据库中用列存储方式存储的一列. 需求 假设我有这样一个数据筛选需求,用SQL表示为: select key from set ...

  7. 【记录一个问题】cv::cuda::dft()比cv::dft()慢很多

    具体的profile调用图如下: 可以看见compute很快,但是构造函数很慢. nvidia官网看到几篇类似的帖子,但是没有讲明白怎么解决的: opencv上的参考文档:https://docs.o ...

  8. Java 异步 I/O

    Java 中的异步 I/O 简称 AIO, A 即 Asynchronous.AIO 在 JDK1.7 时引入,基于操作系统提供的异步 I/O 通信模型,封装了一些进行异步 I/O 操作的 API. ...

  9. javascript 获取<td>标签内的值。

    当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model). HTML DOM 模型被构造为对象的树. 通过可编程的对象模型,JavaScript 获得了足够的能力来 ...

  10. 访问者模式(Visitor模式)

    模式的定义与特点 访问者(Visitor)模式的定义:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提 ...