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

工厂模式的介绍

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

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

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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Kotlin基本语法 4 类

1.定义类 package classStudyclass Player {var name:String "jack"get() field.capitalize()set(value) {field value.trim()} }fun main() {val player Player()println(player.name)player.name " asdas "println(player.name)} 2.计算属性与防范…

【Python】 剪辑法欠采样 CNN压缩近邻法欠采样

借鉴:关于K近邻(KNN),看这一篇就够了!算法原理,kd树,球树,KNN解决样本不平衡,剪辑法,压缩近邻法 - 知乎 但是不要看他里面的代码,因为作者把代码…

QEMU源码全解析 —— virtio(20)

接前一篇文章: 上回书重点解析了virtio_pci_modern_probe函数。再来回顾一下其中相关的数据结构: struct virtio_pci_device struct virtio_pci_device的定义在Linux内核源码/drivers/virtio/virtio_pci_common.h中,如下: /* O…

话说激励广告

一、导言 如果一个入场口令是请问效率秘诀是: _ _ _,_ _ _ _。,然后她会告诉你通过小程序: 点“试彩蛋”,看完视频广告之后可以得到答案,这种形式是不是有点意思。这就是激励广告的一种应用场景。 激励…

[ai笔记8] 聊聊openAI最新文生视频产品-Sora

欢迎来到文思源想的ai空间,这是技术老兵重学ai以及成长思考的第8篇分享! 近期sora在科技届引发不小的轰动,虽然这是openai并未对外发布的相关产品,目前如同小米汽车的技术发布会,但是确实引发了不小的震撼&#xff0c…

Trie树应用(最大异或对)C++(Acwing)

代码&#xff1a; #include <iostream> #include <algorithm>using namespace std;const int N 100010, M 3100010;int n; int a[N], son[M][2], idx;void insert(int x) {int p 0;for (int i 30; i > 0; i -- ){int &s son[p][x >> i & 1]…

Java+SpringBoot:滑雪场管理的技术革新

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

【视频编解码】M-JPEG压缩、H.264压缩 对比

简介 参考这篇文章&#xff1a;https://blog.csdn.net/qq_41248872/article/details/83590337 写的比较好&#xff0c;这里就不赘述了。 我们在视频传输的时候&#xff0c;需要压缩&#xff0c;常见的压缩包括: jpeg 压缩h264 压缩 当然使用最多的还是 264, 毕竟他的压缩比…

我国无水氢氟酸产量逐渐增长 东岳集团市场占比较大

我国无水氢氟酸产量逐渐增长 东岳集团市场占比较大 无水氢氟酸是一种十分重要的化工产品&#xff0c;在常温常压下多表现为一种无色发烟液体。无水氢氟酸具有吸水性强、化学活性高、介电常数高、阻燃性能好等优点。经过多年发展&#xff0c;无水氢氟酸制备方法已经成熟&#xf…

【C++】 类与对象——流操作符重载,const成员函数

类与对象 流操作符重载1 << 重载2 >> 重载 const 修饰Thanks♪(&#xff65;ω&#xff65;)&#xff89;谢谢阅读&#xff01;&#xff01;&#xff01;下一篇文章见&#xff01;&#xff01;&#xff01; 流操作符重载 流操作符功能<<输出操作符>>输…

小程序--模板语法

一、插值{{}}语法 1、内容绑定 <view>{{iptValue}}</view> 2、属性绑定 <switch checked"{{true}}" /> Page({data: {iptValue: 123} }) 二、简易双向数据绑定 model:value&#xff1a;支持双向数据绑定 注&#xff1a;仅input和textarea支持&a…

QT编写工具基本流程(自用)

以后有人让你写工具的时候&#xff0c;可以方便用这个模版及时提高工作效率&#xff0c;可以争取早点下班。包含库目录&#xff0c;头文件目录&#xff0c;输出目录以及翻译和部署&#xff0c;基本上都全了&#xff0c;也可以做收藏用用。 文章目录 1、创建项目Dialog Widget都…

SpringBoot + Nacos + K8s 优雅停机

1 概念 2 用案例说话 案例前&#xff1a;k8s 停机流程 k8s springboot nacos 案例 案例优化 3 再次优化 mq 和 定时任务 流量控制 4 小结 1 概念 优雅停机是什么&#xff1f;网上说的优雅下线、无损下线&#xff0c;都是一个意思。 优雅停机&#xff0c;通常是指在设…

推荐“应用随机过程”学习材料

今天在检索资料的时候&#xff0c;无意间发现了这份由李东风老师的“应用随机过程 (pku.edu.cn)”。

LeetCode.105. 从前序与中序遍历序列构造二叉树

题目 105. 从前序与中序遍历序列构造二叉树 分析 这道题是告诉我们一颗二叉树的前序和中序&#xff0c;让我们根据前序和中序构造出整颗二叉树。 拿到这道题&#xff0c;我们首先要知道前序的中序又怎样的性质&#xff1a; 前序&#xff1a;【根 左 右】中序&#xff1a;…

LeetCode 450.删除二叉搜索树中的节点和669.修建二叉搜索树思路对比 及heap-use-after-free问题解决

题目描述 450.删除二叉搜索树中的节点 给定一个二叉搜索树的根节点 root 和一个值 key&#xff0c;删除二叉搜索树中的 key 对应的节点&#xff0c;并保证二叉搜索树的性质不变。返回二叉搜索树&#xff08;有可能被更新&#xff09;的根节点的引用。 一般来说&#xff0c;…

Python从进阶到高级—通俗易懂版

Python从进阶到高级—通俗易懂版 一、简介 Python 进阶是我一直很想写的&#xff0c;作为自己学习的记录&#xff0c;过去自己在看一些代码的时候经常会困惑&#xff0c;看不懂&#xff0c;然后自己去查资料、看书籍&#xff0c;慢慢的一个个弄懂&#xff0c;经常沉浸其中。关…

Spring Boot项目中TaskDecorator的应用实践

一、前言 TaskDecorator是一个执行回调方法的装饰器&#xff0c;主要应用于传递上下文&#xff0c;或者提供任务的监控/统计信息&#xff0c;可以用于处理子线程与主线程间数据传递的问题。 二、开发示例 1.自定义TaskDecorator import org.springframework.core.task.Task…

算法沉淀——穷举、暴搜、深搜、回溯、剪枝综合练习一(leetcode真题剖析)

算法沉淀——穷举、暴搜、深搜、回溯、剪枝综合练习一 01.全排列02.子集03.找出所有子集的异或总和再求和04.全排列 II05.电话号码的字母组合 01.全排列 题目链接&#xff1a;https://leetcode.cn/problems/permutations/ 给定一个不含重复数字的数组 nums &#xff0c;返回其…

BioTech - 大型蛋白质复合物的组装流程 (CombFold)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/136187314 CombFold是用于预测大型蛋白质复合物结构的组合和分层组装算法&#xff0c;利用AlphaFold2预测的亚基之间的成对相互作用。CombFold的组…