dubbo源码中设计模式——注册中心中工厂模式的应用

news2024/11/6 0:40:45

工厂模式的介绍

工厂模式提供了一种创建对象的方式,而无需指定要创建的具体类。

工厂模式属于创建型模式,它在创建对象时提供了一种封装机制,将实际创建对象的代码与使用代码分离。

应用场景:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

工厂模式包含以下几个核心角色:

  • 抽象产品(Abstract Product):定义了产品的共同接口或抽象类。它可以是具体产品类的父类或接口,规定了产品对象的共同方法。
  • 具体产品(Concrete Product):实现了抽象产品接口,定义了具体产品的特定行为和属性。
  • 抽象工厂(Abstract Factory):声明了创建产品的抽象方法,可以是接口或抽象类。它可以有多个方法用于创建不同类型的产品。
  • 具体工厂(Concrete Factory):实现了抽象工厂接口,负责实际创建具体产品的对象。

UML模型图如下:
在这里插入图片描述

dubbo源码中的应用

所有的注册中心实现,都是通过对应的工厂创建的。工厂类之间的关系如图:
在这里插入图片描述

AbstractRegistryFactory 实现了 RegistryFactory 接口的 getRegistry(URL url)方法,是一个通用实现,主要完成了加锁,以及调用抽象模板方法createRegistry(URL url)创建具体实现等操作,并缓存在内存中。

public Registry getRegistry(URL url) {
        if (registryManager == null) {
            throw new IllegalStateException("Unable to fetch RegistryManager from ApplicationModel BeanFactory. "
                    + "Please check if `setApplicationModel` has been override.");
        }

        Registry defaultNopRegistry = registryManager.getDefaultNopRegistryIfDestroyed();
        if (null != defaultNopRegistry) {
            return defaultNopRegistry;
        }

        url = URLBuilder.from(url)
                .setPath(RegistryService.class.getName())
                .addParameter(INTERFACE_KEY, RegistryService.class.getName())
                .removeParameter(TIMESTAMP_KEY)
                .removeAttribute(EXPORT_KEY)
                .removeAttribute(REFER_KEY)
                .build();

        String key = createRegistryCacheKey(url);
        Registry registry = null;
        boolean check = url.getParameter(CHECK_KEY, true) && url.getPort() != 0;

        // 锁定注册表访问过程以确保注册表的单个实例
        registryManager.getRegistryLock().lock();
        try {
            defaultNopRegistry = registryManager.getDefaultNopRegistryIfDestroyed();
            if (null != defaultNopRegistry) {
                return defaultNopRegistry;
            }

            registry = registryManager.getRegistry(key);
            if (registry != null) {
                return registry;
            }

            //创建注册中心通过 spi/ioc
            registry = createRegistry(url);
            if (check && registry == null) {
                throw new IllegalStateException("Can not create registry " + url);
            }

            if (registry != null) {
                registryManager.putRegistry(key, registry);
            }
        } catch (Exception e) {
            if (check) {
                throw new RuntimeException("Can not create registry " + url, e);
            } else {
                // 1-11 无法获取或创建注册表(服务)对象。
                LOGGER.warn(REGISTRY_FAILED_CREATE_INSTANCE, "", "", "Failed to obtain or create registry ", e);
            }
        } finally {
            // 释放锁
            registryManager.getRegistryLock().unlock();
        }

        return registry;
    }

每种注册中心都有自己具体的工厂类,代码中没有显式的判断。主要是判断方法在就在RegistryFactory接口中,该接口里有一个Registry getRegistry(URL url)方法,该方法上有@Adaptive({“protocol”))注解。

@SPI(scope = APPLICATION)
public interface RegistryFactory {

    /**
     * 配置连接到注册表支持的模式
     */
    @Adaptive({PROTOCOL_KEY})
    Registry getRegistry(URL url);
}

@Adaptive这个注解会自动生成代码实现一些逻辑,它的value参数会从URL中获取protocol键的值,并根据获取的值来调用不同的工厂类。例如,当url.protocol = nacos时,获得NacosRegistryFactory实现类。

dubbo支持的注册中心如下图:
在这里插入图片描述
其中各类的作用如下:

  • AbstractRegistry:提供由缓存文件支持的故障保护注册表服务。当注册表中心崩溃时,使用者/提供者仍然可以找到彼此。
  • FailbackRegistry:提供自动重试功能的注册表服务的模板实现。
  • CacheableFailbackRegistry:基于FailbackRegistry,它添加了URLAddress和URLParam缓存以节省RAM空间。
  • ServiceDiscoveryRegistry:ServiceDiscoveryRegistry是一个非常特殊的Registry实现,用于桥接旧的接口级服务发现模型。其中在3.0中以兼容的方式引入了新的服务发现模型。
  • NacosRegistry:Nacos注册中心
  • MulticastRegistry:Multicast 注册中心不需要启动任何中心节点,只要广播地址一样,就可以互相发现。
  • ZookeeperRegistry:zookeeper注册中心

总结

本文深入探讨了Dubbo框架中注册中心组件的设计与实现。介绍了工厂模式的基本概念以及它在设计模式中的角色。通过源码分析,揭示了Dubbo是如何利用工厂模式来管理不同类型的注册中心实例,如ZooKeeper、Nacos等,以及如何通过扩展接口来实现对新注册中心类型的快速支持。

Dubbo注册中心的设计体现了工厂模式的强大之处,为构建灵活、可扩展的分布式系统提供了有力的设计参考。通过继续探索和实践这些设计原则,我们可以进一步提升我们的系统设计能力,以应对不断变化的技术挑战。

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

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

相关文章

深入理解C语言(5):程序环境和预处理详解

文章主题:程序环境和预处理详解🌏所属专栏:深入理解C语言📔作者简介:更新有关深入理解C语言知识的博主一枚,记录分享自己对C语言的深入解读。😆个人主页:[₽]的个人主页&#x1f3c4…

C++ 八数码问题理解 `IDA*` 算法原则:及时止损,缘尽即散

1.前言 八数码是典型的状态搜索案例。如字符串转换问题、密码锁问题都是状态搜索问题。 状态搜索问题指由一种状态转换到到最终状态,求解中间需要经过多少步转换,或者说最小需要转换多少步,或者说有多少种转换方案。本文和大家聊聊八数码问…

【QT 5 +Linux下软件桌面快捷方式+qt生成软件创建桌面图标+学习他人文章+第二篇:编写桌面文件.desktop】

【QT 5 Linux下软件桌面快捷方式qt生成软件创建桌面图标学习他人文章第二篇:编写桌面文件.desktop】 1、前言2、实验环境3、自我学习总结-本篇总结1、新手的疑问,做这件事目的2、了解.desktop3、三个关键目录以及文件编写1、目录:/opt/2、目录…

threeJS 全屏或非全屏状态下鼠标点击获取屏幕位置

使用threeJS引入模型进行点击事件,其实有一个是将获取到坐标位置进行webgl坐标系的转换 全屏状态: 全屏状态下直接利用window.innerWidth和 window.innerHeight进行计算即可,代码如下 // 校验控制器旋转的时候不触发点击事件boxClickEvent(…

【2024软件测试面试必会技能】Selenium(6):元素定位_xpath定位

XPATH是什么 XPATH是一门在XML文档中查找信息的语言,XPATH可用来在XML文档中对元素和属性进行遍历,主流的浏览器都支持XPATH,因为HTML页面在DOM中表示为XHTML文档。Selenium WebDriver支持使用XPATH表达式来定位元素。 Xpath常用如下6种定位…

《论文阅读》e-CARE:探索可解释因果推理的新数据集 ACL2022

《论文阅读》e-CARE:探索可解释因果推理的新数据集 ACL2022 前言简介数据集优势数据集语料级别的统计数据集示例评分标准前言 今天为大家带来的是《e-CARE: a New Dataset for Exploring Explainable Causal Reasoning》 出版:ACL 时间:2022 类型:因果推理 关键词:情绪…

virtualbox虚拟机运行中断,启动报错“获取 VirtualBox COM 对象失败”

文章目录 问题现象排查解决总结 问题现象 2月7日下午四点多,我已经休假了,某县的客户运维方打来电话,说平台挂了,无法访问客户是提供的一台Windows server机器部署平台,是使用virtualbox工具安装的CentOS7.9虚拟机和运…

Linux基础知识——Linux是什么及发展史

文章目录 Linux是什么Linux之前Unix发展史MulticsUnicsUnixUNIX分支--BSDUNIX分支--System VMinixGUN计划GPLXFree86Linux 开源软件和闭源软件开源软件闭源软件/专利软件(copyright) Linux的内核版本Linux发行版 Linux是什么 Linux到底是操作系统还是应用程序呢?Li…

2024最佳住宅代理IP服务商

跨境出海已成为了近几年的最热趋势,大批量的企业开始开拓海外市场,而海外电商领域则是最受欢迎的切入口。新兴的tiktok、Temu,老牌的Amazon、Ebay,热门的Etsy、Mecari等等都是蓝海一片。跨境入门并不难,前期的准备中不…

论文精读--Noisy Student

一个 EfficientNet 模型首先作为教师模型在标记图像上进行训练,为 300M 未标记图像生成伪标签。然后将相同或更大的 EfficientNet 作为学生模型并结合标记图像和伪标签图像进行训练。学生网络训练完成后变为教师再次训练下一个学生网络,并迭代重复此过程…

图形系统开发实战课程:进阶篇(上)——6.图形交互操作:拾取

图形开发学院|GraphAnyWhere 课程名称:图形系统开发实战课程:进阶篇(上)课程章节:“图形交互操作:拾取”原文地址:https://www.graphanywhere.com/graph/advanced/2-6.html 第六章 图形交互操作:拾取 \quad 在图形系统…

Linux中安装Nginx及日常配置使用

高性能的http服务器/反向代理服务器。官方测试支持5万并发,CPU、内存等消耗较低且运行稳定 使用场景 Http服务器。 Nginx可以单独提供Http服务,做为静态网页的服务器。虚拟主机。 可以在一台服务器虚拟出多个网站。反向代理与负载均衡。 Nginx做反向代理…

创建型设计模式 - 原型设计模式 - JAVA

原型设计模式 一 .简介二. 案例三. 补充知识 前言 这是我在这个网站整理的笔记,有错误的地方请指出,关注我,接下来还会持续更新。 作者:神的孩子都在歌唱 一 .简介 原型模式提供了一种机制,可以将原始对象复制到新对象&#xff0…

Linux篇:进程

一. 前置知识 1.1冯诺依曼体系结构 我们常见的计算机,如笔记本。我们不常见的计算机,如服务器,大部分都遵守冯诺依曼体系 为什么计算机要采用冯诺依曼体系呢? 在计算机出现之前有很多人都提出过计算机体系结构,但最…

vite是什么

vite 是什么 vite —— 一个由 vue 作者尤雨溪开发的 web 开发工具 Vite由两个主要部分组成 dev server:利用浏览器的ESM能力来提供源文件,具有丰富的内置功能并具有高效的HMR生产构建:生产环境利用Rollup来构建代码,提供指令用…

基于SSM的绿色农产品销售系统的设计与实现

随着电子商务在各行各业中的广泛应用,为更多的产品提供了销售渠道。但就目前来看,这些以工业产品为热销的大型综合性电商平台,农产品销售量很不理想。另外,市面上存在专门销售农产品的网站,大部分消费者没有形成在网上购买农产品的…

C语言每日一题(60)对链表进行插入排序

题目链接 力扣网 147 对链表进行插入排序 题目描述 给定单个链表的头 head ,使用 插入排序 对链表进行排序,并返回 排序后链表的头 。 插入排序 算法的步骤: 插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有…

虚拟列表【vue】等高虚拟列表/非等高虚拟列表

文章目录 1、等高虚拟列表2、非等高虚拟列表 1、等高虚拟列表 参考文章1 参考文章2 <!-- eslint-disable vue/multi-word-component-names --> <template><divclass"waterfall-wrapper"ref"waterfallWrapperRef"scroll"handleScro…

Kubernetes部署CNI网络组件

目录 1.概述 K8S的三种网络 VLAN和VXLAN的区别 K8S中Pod网络通信 flannel的三种模式 flannel的UDP模式工作原理 flannel的VXLAN模式工作原理 2.部署flannel 在node01节点上操作 在master01节点上操作 3.部署Calico Calico主要由三个部分组成 calico的IPIP模式工作…

Spring6学习技术|Junit

学习材料 尚硅谷Spring零基础入门到进阶&#xff0c;一套搞定spring6全套视频教程&#xff08;源码级讲解&#xff09; Junit 背景 背景就是每次Test都要重复创建容器&#xff0c;获取对象。就是ApplicationContext和getBean两个语句。通过Spring整合Junit&#xff0c;可以…