dubbo3 Cluster wrapper初始化及extensionloader分析

news2024/11/18 3:33:07

从以下代码,可以看到dubbo默认的服务是failover

@SPI("failover")
public interface Cluster {
    String DEFAULT = "failover";

    @Adaptive
    <T> Invoker<T> join(Directory<T> directory, boolean buildFilterChain) throws RpcException;

    static Cluster getCluster(ScopeModel scopeModel, String name) {
        return getCluster(scopeModel, name, true);
    }

    static Cluster getCluster(ScopeModel scopeModel, String name, boolean wrap) {
        if (StringUtils.isEmpty(name)) {
            name = "failover";
        }

        return (Cluster)ScopeModelUtil.getApplicationModel(scopeModel).getExtensionLoader(Cluster.class).getExtension(name, wrap);
    }
}

但是debug,可以看到cluster 调到了MockClusterWrapper,这个是怎么来的呢?

在这里插入图片描述
核心代码都在ExtensionLoader 类里面,
先看load

  private void loadClass(ClassLoader classLoader, Map<String, Class<?>> extensionClasses,
                           java.net.URL resourceURL, Class<?> clazz, String name,
                           boolean overridden) {
        if (!type.isAssignableFrom(clazz)) {
            throw new IllegalStateException(
                    "Error occurred when loading extension class (interface: " + type + ", class line: " + clazz.getName() + "), class " + clazz.getName() + " is not subtype of interface.");
        }
        if (name.equals("failover")){
            logger.info("failover debug ");
        }
        boolean isActive = loadClassIfActive(classLoader, clazz);

        if (!isActive) {
            return;
        }

        if (clazz.isAnnotationPresent(Adaptive.class)) {
            cacheAdaptiveClass(clazz, overridden);
        } else if (isWrapperClass(clazz)) {
            cacheWrapperClass(clazz);
        } else {
            if (StringUtils.isEmpty(name)) {
                name = findAnnotationName(clazz);
                if (name.length() == 0) {
                    throw new IllegalStateException(
                            "No such extension name for the class " + clazz.getName() + " in the config " + resourceURL);
                }
            }

            String[] names = NAME_SEPARATOR.split(name);
            if (ArrayUtils.isNotEmpty(names)) {
                cacheActivateClass(clazz, names[0]);
                for (String n : names) {
                    cacheName(clazz, n);
                    saveInExtensionClass(extensionClasses, clazz, n, overridden);
                }
            }
        }
    }

这里进行了cache。

这个函数是被loadResource调用

private void loadResource(Map<String, Class<?>> extensionClasses, ClassLoader classLoader,
                              java.net.URL resourceURL, boolean overridden,
                              String[] includedPackages, String[] excludedPackages,
                              String[] onlyExtensionClassLoaderPackages) {
        try {
            List<String> newContentList = getResourceContent(resourceURL);
            String clazz;
            for (String line : newContentList) {

Cluster load的extension 的resouce文件是
在这里插入图片描述
这是放在internal目录下,使用internal load Strategy优先load的。
在这里插入图片描述
dubbo 实际定了4种strategy,但DubboLoadingStrategy 没有被实际使用。
ServicesLoadingStrategy “META-INF/services/”
DubboExternalLoadingStrategy META-INF/dubbo/external/
DubboInternalLoadingStrategy META-INF/dubbo/internal/
DubboLoadingStrategy META-INF/dubbo/

是否wrapper,不是通过名称,而是通过构造函数,具体代码如下:

protected boolean isWrapperClass(Class<?> clazz) {
    Constructor<?>[] constructors = clazz.getConstructors();
    for (Constructor<?> constructor : constructors) {
        if (constructor.getParameterTypes().length == 1 && constructor.getParameterTypes()[0] == type) {
            return true;
        }
    }
    return false;
}

而最后组装Cluster的代码如下:

if (CollectionUtils.isNotEmpty(wrapperClassesList)) {
    for (Class<?> wrapperClass : wrapperClassesList) {
        Wrapper wrapper = wrapperClass.getAnnotation(Wrapper.class);
        boolean match = (wrapper == null) || ((ArrayUtils.isEmpty(
                wrapper.matches()) || ArrayUtils.contains(wrapper.matches(),
                name)) && !ArrayUtils.contains(wrapper.mismatches(), name));
        if (match) {
            instance = injectExtension(
                    (T) wrapperClass.getConstructor(type).newInstance(instance));
            instance = postProcessAfterInitialization(instance, name);
        }
    }
}

以上的 newInstance就是第一张图中的调用过程。

注意是生成instance是下一个wrapper 类的构造函数的参数,最后返回的是最后一个wrapper类。

因此最后生成的类如下

在这里插入图片描述

如果配置了其它模式,如failfast,也是类似的。

PS class类无需加activate annotation,而filter必须有。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/654513.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

达梦MPP集群搭建、DEM管理工具搭建MPP集群应用

说明... 3 两节点MPP集群手动搭建... 4 1、配置dm.ini 4 2、配置dmmal.ini 5 3、配置dmmpp.ctl 5 4、启动EP01和EP02数据库实例&#xff0c;系统搭建完成。... 6 MPP使用&#xff1a;... 6 使用DEM管理系统搭建MPP3节点集群... 10 一、达梦DEM部署... 11 1、创建DEM库…

计算机网络管理 常见的计算机网络管理工具snmputil,Mib browser,SNMPc管理软件的功能和异同

⬜⬜⬜ &#x1f430;&#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea;(*^▽^*)欢迎光临 &#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea;&#x1f430;⬜⬜⬜ ✏️write in front✏️ &#x1f4dd;个人主页&#xff1a;陈丹宇jmu &am…

【C++ 基础篇:25】:【重要模板】C++ 算术(赋值)运算符重载及自增自减运算符重载【以 Date 日期类为例】

系列文章说明 本系列 C 相关文章 仅为笔者学习笔记记录&#xff0c;用自己的理解记录学习&#xff01;C 学习系列将分为三个阶段&#xff1a;基础篇、STL 篇、高阶数据结构与算法篇&#xff0c;相关重点内容如下&#xff1a; 基础篇&#xff1a;类与对象&#xff08;涉及C的三大…

LabVIEW开发监测太阳能电池和损伤检测

LabVIEW开发监测太阳能电池和损伤检测 使用LabVEW监测太阳能电池的实时数据&#xff0c;利用LabVIEW实现太阳能跟踪和损伤检测。使用了太阳能电池板&#xff0c;Arduino UNO板&#xff0c;电压&#xff08;0-25V&#xff09;传感器LDR&#xff0c;温度传感器和伺服电机。Solar…

基于ubuntu20.4搭建的K8S集群新增工作节点带GPU显卡过程记录

基于ubuntu20.4搭建的K8S集群新增工作节点带GPU显卡过程记录 1、创建虚拟机引导选择efi 2、添加显卡,修改虚拟机-高级参数,添加以下两个参数 pciPassthru.64bitMMIOSizeGB:192 pciPassthru.use64bitMMIO:TRUE否则可能无法开机。 3、添加直通显卡,安装显卡驱动。 3.1、查…

Redis集群详细介绍从0开始-包括集群的Jedis开发

集群 为什么需要集群-高可用性 1、生产环境的实际需求和问题 容量不够&#xff0c;redis 如何进行扩容&#xff1f;并发写操作&#xff0c; redis 如何分摊&#xff1f;主从模式&#xff0c;薪火相传模式&#xff0c;主机宕机&#xff0c;会导致ip 地址发生变化&#xff0c;…

linuxOPS系统服务_linux文件权限管理

什么是权限 **权限&#xff1a;**在计算机系统中&#xff0c;权限是指某个计算机用户具有使用软件资源的权利。 权限的目的 文件权限的设置目的&#xff1a;是想让某个用户有权利操作文件 权限的分类 普通权限rwx 用户正常情况去操作文件所具有的权限 高级权限st 用户对某…

FPGA基础知识-任务和函数

目录 学习目标 学习内容 1.任务和函数的区别 2.任务 3.函数 学习时间 学习总结 学习目标&#xff1a; 1.理解任务和函数之间的区别。 2.理解定义任务所需的条件&#xff0c;学会任务的声明和调用。 3.理解定义函数所需的条件&#xff0e;学会函数的声明和调用。 学习…

JavaScript之ES6高级语法(四)

本文是我在学习过程中记录学习的点点滴滴&#xff0c;目的是为了学完之后巩固一下顺便也和大家分享一下&#xff0c;日后忘记了也可以方便快速的复习。 ES6高级语法(四&#xff09; 前言一、深浅拷贝1.1、浅拷贝1.2、深拷贝1.2.1、递归实现深拷贝1.2.2、js库lodash里面cloneDee…

你们软件测试面试最难的一道题是什么?

在测试面试时&#xff0c;面试官往往会出一个简单的场景让大家进行测试点设计来考察大家的测试设计能力&#xff0c;题目看似简单实则蕴藏杀机&#xff0c;测试人员需要根据自己的工作年限做出不同的回答方可过关。 如果你工作1-2年&#xff0c;那么你只需要回答功能方面的测试…

源来Intel——开放原子全球峰会

文章目录 Intel的开源之路AI领域边缘人工智能在中国的发展趋势边缘人工智能领域的挑战生态系统解决方案英特尔针对边缘人工智能的产品总结 英特尔基础软件赋能中国生态Intel : 软件优先 推动中国市场中国Linux操作系统生态Intel全力投入中国开源社区开发国产Linux厂商&#xff…

I2C中的时钟同步与仲裁

时钟同步和仲裁 在单主设备中&#xff0c;不需要时钟同步和仲裁。而在多设备时&#xff0c;多个主设备可以同时在空闲的总线上开始发送数据&#xff0c;这时就需要仲裁决定哪一个来控制总线并完成它的数据传输&#xff0c;有时候也需要时钟同步来协同设备间的工作。而这正是通过…

Android音视频开发实战02-Jni

一 JNI 1.1 什么是JNI JNI是Java Native Interface的缩写&#xff0c;是Java提供的一种机制&#xff0c;用于在Java代码中调用本地&#xff08;C/C&#xff09;代码。它允许Java代码与本地代码进行交互&#xff0c;通过JNI&#xff0c;Java应用程序可以调用一些原生库或者操作…

Maven编译常见问题收集

1、父pom里面有引入lombok依赖&#xff0c;为什么子pom有用到lombok&#xff0c;依然识别不到呢 这是因为父pom引入依赖的时候&#xff0c;把 <dependency></dependency>依赖标签&#xff0c;最外层包 在了<dependencyManagement></dependencyManagemen…

Python学了基本语法 下一步该干什么 ?

刚入门Python,学习了基本语法后&#xff0c;你可以开始编写简单的程序了。接下来&#xff0c;你可以学习Python的标准库和第三方库&#xff0c;掌握更多的编程技巧和知识&#xff0c;提高自己的编程能力。同时&#xff0c;也可以通过实践项目来巩固所学知识&#xff0c;提高自己…

web3描述以太坊与区块链之间的操作关系

好通过前面两篇文章 Web3.0概念 web3带大家简单建立区块链概念 大家开始明白 web3.0是基于区块链为基础开发的 我们讲区块链多次提到以太坊 EVM 那这个东西到底是什么呢&#xff1f; 就现在的情况来讲 从零到一去搭建一个区块链环境 那可太难了 所以 以太坊一开始 确实是做一…

关于GPT-3和GPT-4,你需要知道都在这里

友情提示 提示&#xff1a;本文约3500个文字&#xff0c;字数较长&#xff0c;可直接点击序号进入相关目录阅读字数 文章目录 友情提示前言一、什么是 GPT-3、GPT-4 和 ChatGPT&#xff1f;二、对未来的担忧三、什么时候可以用GPT4&#xff1f;四、GPT-4用在什么地方五、GPT-4能…

json_decode返回NULL

json_decode返回NULL 最近在调用某公司的API时&#xff0c;将对方返回的数据&#xff0c;使用PHP的json_decode函数解析&#xff0c;但是返回NULL,最终排查为对方传送来的json格式有误 打印$_REQUEST&#xff0c;数据结构大致如下&#xff1a; 1 2 3 4 5 6 7 8 9 10 array (…

Android 面试延伸技术点有哪些,你能答上几个?

1、如何进行单元测试&#xff0c;如何保证 App 稳定 &#xff1f; 参考回答&#xff1a; 要测试 Android 应用程序&#xff0c;通常会创建以下类型自动单元测试 本地测试&#xff1a;只在本地机器 JVM 上运行&#xff0c;以最小化执行时间&#xff0c;这种单元测试不依赖于 An…

JavaScript之ES6高级语法(三)

本文是我在学习过程中记录学习的点点滴滴&#xff0c;目的是为了学完之后巩固一下顺便也和大家分享一下&#xff0c;日后忘记了也可以方便快速的复习。 ES6高级语法(三&#xff09; 前言一、原型对象1.1、constructor 属性1.2、对象原型 二、原型继承三、原型链 前言 今天学习的…