Dubbo之DubboBootstrap源码解析

功能描述

  • DubboBootstrap是Dubbo的启动类,包含服务启动、初始化、预处理配置、销毁清理等核心功能

功能分析

核心DubboBootstrap类分析

主要成员变量分析

private static volatile DubboBootstrap instance; //缓存者启动类的实例对象,以static形式存储,便于其它类调用private final AtomicBoolean awaited = new AtomicBoolean(false); //是否等待private final Lock lock = new ReentrantLock();private final Condition condition = lock.newCondition();private final Lock destroyLock = new ReentrantLock(); //销毁清理时用到的锁private final ExecutorService executorService = newSingleThreadExecutor();private final EventDispatcher eventDispatcher = EventDispatcher.getDefaultExtension(); //事件派发器private final ExecutorRepository executorRepository = getExtensionLoader(ExecutorRepository.class).getDefaultExtension(); //线程池仓库private final ConfigManager configManager; //配置管理器private final Environment environment;private ReferenceConfigCache cache; //引用配置的缓存对象private volatile boolean exportAsync; //是否异步暴露private volatile boolean referAsync; //是否异步引用private AtomicBoolean initialized = new AtomicBoolean(false); //初始化标识private AtomicBoolean started = new AtomicBoolean(false); //启动标识private AtomicBoolean ready = new AtomicBoolean(true); //是否已经准备好环境private AtomicBoolean destroyed = new AtomicBoolean(false);private volatile ServiceInstance serviceInstance; //服务实例private volatile MetadataService metadataService; //元数据服务private volatile Set<MetadataServiceExporter> metadataServiceExporters;private List<ServiceConfigBase<?>> exportedServices = new ArrayList<>(); //已经暴露的服务列表private List<Future<?>> asyncExportingFutures = new ArrayList<>(); //异步暴露时使用的Future列表

主要成员方法分析

获取DubboBootstrap的实例对象

public static DubboBootstrap getInstance() { //获取实例(使用单例模式)if (instance == null) {synchronized (DubboBootstrap.class) {if (instance == null) { //synchronized + 双重检查,线程安全且缩小锁的范围instance = new DubboBootstrap();}}}return instance;
}

私有的构造函数

private DubboBootstrap() { //私有的构造函数configManager = ApplicationModel.getConfigManager(); //config对象的本地配置environment = ApplicationModel.getEnvironment();     //获取环境信息DubboShutdownHook.getDubboShutdownHook().register();ShutdownHookCallbacks.INSTANCE.addCallback(new ShutdownHookCallback() { //注册钩子函数,当容器停止时,对DubboBootstrap进行销毁处理@Overridepublic void callback() throws Throwable {DubboBootstrap.this.destroy();}});
}

做初始化

public void initialize() { //初始化if (!initialized.compareAndSet(false, true)) {return; //此处initialized为true时进入,表明是已经初始化过来,就不在初始化}ApplicationModel.initFrameworkExts(); //初始化框架配置startConfigCenter(); //启动配置中心(拉取远程的配置写到本地缓存中)loadRemoteConfigs(); //加载远程配置(包含RegistryConfig、ProtocolConfig)、并写到ConfigManager对应的缓存中checkGlobalConfigs(); //检查Config是否正确startMetadataCenter(); //启动元数据中心initMetadataService(); //创建MetadataService实例(通过SPI接口WritableMetadataService的实例创建)initMetadataServiceExports(); //创建MetadataServiceExporter实例的集合initEventListener(); //将当前对象作为监听器加入到缓存中的监听器列表if (logger.isInfoEnabled()) {logger.info(NAME + " has been initialized!");}
}

启动服务

public DubboBootstrap start() {if (started.compareAndSet(false, true)) {ready.set(false); //设置标志值initialize();//初始化处理if (logger.isInfoEnabled()) {logger.info(NAME + " is starting...");}exportServices(); //暴露服务if (!isOnlyRegisterProvider() || hasExportedServices()) {exportMetadataService(); //暴露元数据registerServiceInstance(); //注册服务到注册中心}referServices(); //引用服务if (asyncExportingFutures.size() > 0) { //服务异步暴露后,更新启动标志new Thread(() -> {try {this.awaitFinish(); //阻塞着等待异步任务完成} catch (Exception e) {logger.warn(NAME + " exportAsync occurred an exception.");}ready.set(true);if (logger.isInfoEnabled()) {logger.info(NAME + " is ready.");}}).start();} else { //服务同步暴露后,更新启动标志ready.set(true);if (logger.isInfoEnabled()) {logger.info(NAME + " is ready.");}}if (logger.isInfoEnabled()) { //dubbo启动完成的日志logger.info(NAME + " has started.");}}return this;
}

做销毁清理

public void destroy() { //做销毁清理工作(包含关联的注册信息、元数据信息、暴露服务信息等)if (destroyLock.tryLock()) { //尝试加锁做清理,保证线程安全try {DubboShutdownHook.destroyAll(); //停机钩子线程做销毁工作if (started.compareAndSet(true, false)&& destroyed.compareAndSet(false, true)) { //在服务已启动且未销毁时,才做清理unregisterServiceInstance(); //会发起远程调用,取消注册的服务,比如若注册中心为zookeeper,则会通过curator,取消注册的服务unexportMetadataService(); //取消元数据暴露unexportServices(); //从ConfigMananer移除暴露的服务缓存unreferServices(); //取消服务引用destroyRegistries(); //销毁注册实例(即关闭注册中心客户端,以及移除注册实例在本地的缓存)DubboShutdownHook.destroyProtocols(); //销毁所有协助,并释放协议所在的资源destroyServiceDiscoveries(); //移除服务实例,即ServiceDiscovery实例clear(); //清除配置信息shutdown(); //停止运行中的线程池release(); //唤醒所有线程,将该执行的任务执行完,然后再做释放处理}} finally {destroyLock.unlock();}}
}

关联GenericEventListener类分析

主要成员变量分析

private final Method onEventMethod; //onEvent(Event)方法对应的Methodprivate final Map<Class<?>, Set<Method>> handleEventMethods; //维护着事件与事件触发的方法的关系
  • 代码解析:GenericEventListener是事件监听器,维护着事件以及触发事件的方法

主要成员方法分析

查找处理事件的方法

private Map<Class<?>, Set<Method>> findHandleEventMethods() {Map<Class<?>, Set<Method>> eventMethods = new HashMap<>();of(getClass().getMethods()).filter(this::isHandleEventMethod) //过滤出符合条件处理事件的方法.forEach(method -> {Class<?> paramType = method.getParameterTypes()[0];Set<Method> methods = eventMethods.computeIfAbsent(paramType, key -> new LinkedHashSet<>());methods.add(method);});return eventMethods;
}

执行事件对应的方法

public final void onEvent(Event event) { Class<?> eventClass = event.getClass();handleEventMethods.getOrDefault(eventClass, emptySet()).forEach(method -> {ThrowableConsumer.execute(method, m -> {m.invoke(this, event); //依次执行事件关联的方法});});
}

关联EventListener接口分析

@SPI
@FunctionalInterface
public interface EventListener<E extends Event> extends java.util.EventListener, Prioritized { //事件监听器void onEvent(E event); //事件处理static Class<? extends Event> findEventType(Class<?> listenerClass) { //根据监听器Class查找对应的事件Class(就是查找 EventListener<E extends Event> 中的泛化类型)Class<? extends Event> eventType = null;if (listenerClass != null && EventListener.class.isAssignableFrom(listenerClass)) { //isAssignableFrom判断一个类或接口是否是另一个类超类或父接口eventType = findParameterizedTypes(listenerClass).stream().map(EventListener::findEventType) //找到事件的实际类型.filter(Objects::nonNull).findAny().orElse((Class) findEventType(listenerClass.getSuperclass())); //若都没找到,则找它的父类对应的事件类型}return eventType;}static Class<? extends Event> findEventType(ParameterizedType parameterizedType) { //根据参数化的类型找到事件类型Class<? extends Event> eventType = null;Type rawType = parameterizedType.getRawType(); //获取泛型参数if ((rawType instanceof Class) && EventListener.class.isAssignableFrom((Class) rawType)) { //泛型参数为EventListener进行处理Type[] typeArguments = parameterizedType.getActualTypeArguments(); //获取实际的参数列表for (Type typeArgument : typeArguments) {if (typeArgument instanceof Class) {Class argumentClass = (Class) typeArgument;if (Event.class.isAssignableFrom(argumentClass)) { //找到类型为Event的参数eventType = argumentClass;break;}}}}return eventType;}
}
  • 代码解析:EventListener是SPI接口,也是函数式接口,通过事件监听处理对应的事件,类似Handle处理类。该接口继承了java中EventListener,因为所有事件监听器接口都必须扩展的标记接口EventListener。

问题点答疑

  • DubboBootstrap主要负责启动加载哪些信息?是从哪里进入到DubboBootStrap类的?

    • 解答:执行逻辑在DubboBootstrapApplicationListener#onApplicationContextEvent中,也就是在spring容器启动后监听容器发布的时间,里面有调用dubboBootstrap.start(); dubbo服务的启动方法
  • DubboBootstrap怎么实现优雅停机?

    • 解答:通过在创建DubboBootstrap实例时注册钩子函数,当容器停止时,对DubboBootstrap进行销毁处理,会将相关的清理操作处理,所有的任务处理完,才会关闭服务。
  • java.util.EventListener的功能用途是啥?

    • 解答:java中EventListener是一个标记接口,java规定所有的事件都要继承该接口。
  • 停机时ShutdownHookCallbacks#addCallback,是怎么进入此处的回调方法的?

    • 解答:在DubboShutdownHook#run线程被执行时,就会执行回调方法ShutdownHookCallbacks#callback,会依次执行已经注册的List钩子回调接口的callback方法

归纳总结

  • DubboBootstrap类是Dubbo的启动类,主要功能包括:
    • Config配置初始化以及合法性检查
    • 服务启动、服务注册、服务引用
    • 注册钩子、服务销毁时做清理

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

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

相关文章

Mr. Cappuccino的第63杯咖啡——Spring之AnnotationConfigApplicationContext源码分析

Spring之AnnotationConfigApplicationContext源码分析 源码分析 源码分析 以上一篇文章《Spring之Bean的生命周期》的代码进行源码分析 AnnotationConfigApplicationContext applicationContext new AnnotationConfigApplicationContext(SpringConfig02.class); LifeCycleBe…

第17集丨Vue中的render函数

目录 一、脚手架中不能使用template配置二、基本使用三、关于不同版本的Vue 一、脚手架中不能使用template配置 // 引入vue import Vue from vue import App from ./Appnew Vue({el:#app,template:<h1>hhh</h1>,comments:{App},})上面案例中&#xff0c;配置了temp…

电子商务的安全防范

(1)安全协议问题&#xff1a;我国大多数尚处在 SSL&#xff08;安全套接层协议&#xff09;的应用上&#xff0c;SET 协议的应用还只是刚刚试验成功&#xff0c;在信息的安全保密体制上还不成熟&#xff0c;对安全协议 还没有全球性的标准和规范&#xff0c;相对制约了国际性…

Mac 使用 rar 命令行工具解压和压缩文件

在 Mac 中常遇到的压缩文件有 zip 和 rar 格式的&#xff0c;如果是 zip 格式的 Mac 系统默认双击一下文件就能直接解压了&#xff0c;但 rar 文件就不行。 需要额外下载 rar 工具了实现。 第一步&#xff1a;下载 rar 工具 工具网址&#xff1a;https://www.rarlab.com/dow…

大语言模型之四-LlaMA-2从模型到应用

最近开源大语言模型LlaMA-2火出圈&#xff0c;从huggingface的Open LLM Leaderboard开源大语言模型排行榜可以看到LlaMA-2还是非常有潜力的开源商用大语言模型之一&#xff0c;相比InstructGPT&#xff0c;LlaMA-2在数据质量、培训技术、能力评估、安全评估和责任发布方面进行了…

微服务—远程调用(RestTemplate)

在微服务的所有框架中&#xff0c;SpringCloud脱颖而出&#xff0c;它是目前国内使用的最广泛的微服务框架 &#xff08;官网地址&#xff09;&#xff0c;它集成了各种微服务功能组件&#xff0c;并基于SpringBoot实现了这些组件的自动装配&#xff0c;从而提供了良好的开箱…

3D- vista:预训练的3D视觉和文本对齐Transformer

论文&#xff1a;https://arxiv.org/abs/2308.04352 代码: GitHub - 3d-vista/3D-VisTA: Official implementation of ICCV 2023 paper "3D-VisTA: Pre-trained Transformer for 3D Vision and Text Alignment" 摘要 三维视觉语言基础(3D- vl)是一个新兴领域&…

在 React+Typescript 项目环境中创建并使用组件

上文 ReactTypescript清理项目环境 我们将自己创建的项目环境 好好清理了一下 下面 我们来看组件的创建 组件化在这种数据响应式开发中肯定是非常重要的。 我们现在src下创建一个文件夹 叫 components 就用他专门来处理组件业务 然后 我们在下面创建一个 hello.tsx 注意 是t…

Azure共享映像库构建VM镜像

什么是Azure共享映像库 Azure共享映像库是一项在Microsoft Azure中以共享方式存储和管理映像的服务。映像是预配置的虚拟机操作系统和应用程序的快照&#xff0c;可以用来创建多个虚拟机实例。通过将映像存储在共享映像库中&#xff0c;用户可以轻松地共享映像给其他Azure订阅…

go文件基本操作

一、文件读操作 文件内容如下&#xff1a; 水陆草木之花&#xff0c;可爱者甚蕃。 晋陶渊明独爱菊。自李唐来&#xff0c;世人甚爱牡丹。 予独爱莲之出淤泥而不染&#xff0c;濯清涟而不妖&#xff0c;中通外直&#xff0c;不蔓不枝&#xff0c;香远益清&#xff0c;亭亭净植…

探索无限创造力的星辰大道,画出想象的浩瀚宇宙!-turtle

介绍 视频教程地址在此&#xff1a;https://www.bilibili.com/video/BV1Pm4y1H7Tb/ 大家好&#xff0c;欢迎来到本视频&#xff01;今天&#xff0c;我们将一同探索Python编程世界中的一个有趣而创意的库——Turtle库。无需专业绘画技能&#xff0c;你就可以轻松地用代码绘制…

【微服务技术一】Eureka、Nacos、Ribbon(配置管理、注册中心、负载均衡)

微服务技术一 技术栈图一、注册中心Eureka概念&#xff1a;搭建EurekaServer服务注册服务发现&#xff08;消费者对提供者的远程调用&#xff09; 二、Ribbon负载均衡负载均衡的原理&#xff1a;LoadBalanced负载均衡的策略&#xff1a;IRule懒加载 三、Nacos注册中心Nacos的安…

elementplus select选择框自动展开方法

select选择器下拉框自动展开显示 // 通过:name的方法可以从ref里面拿到当前选择框绑定的值来做判断 //&#xff08;仅针对于循环出来的多个选择框的情况下&#xff09; <el-select v-model"value" placeholder"Select"><el-optionref"selec…

什么是单例模式

什么是单例模式 文章目录 什么是单例模式1. 单例(单个的实例)2. 单例模式应用实例3. 饿汉式 VS 懒汉式 1. 单例(单个的实例) 所谓类的单例设计模式&#xff0c;就是采取一定的方法保证在整个的软件系统中&#xff0c;对某个类只能存在一个对象实例&#xff0c;并且该类只提供一…

使用 useEffect 和 reactStrictMode:优化 React 组件的性能和可靠性

使用useEffect和React.StrictMode是一种优化React组件性能和可靠性的常见做法。下面是关于如何使用这两个特性的示例&#xff1a; import React, { useEffect } from react;function MyComponent() {useEffect(() > {// 在组件挂载/更新时执行的副作用代码// 可以进行数据获…

nginx介绍

Nginx是什么&#xff1f; Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件&#xff08;IMAP/POP3&#xff09;代理服务器。其特点是占有内存少&#xff0c;并发能力强&#xff0c;事实上nginx的并发能力确实在同类型的网页服务器中表现较好&#xff0c;中国大陆使用ng…

android wifi扫描 framework层修改扫描间隔

frameworks/opt/net/wifi/service/java/com/android/server/wifi/ScanRequestProxy.java 这个也就是说前台应用可以在120s(2分钟) 扫描 4 次 * a) Each foreground app can request a max of* {link #SCAN_REQUEST_THROTTLE_MAX_IN_TIME_WINDOW_FG_APPS} scan every* {l…

08-微信小程序视图层

08-微信小程序视图层 文章目录 视图层 ViewWXML数据绑定列表渲染条件渲染模板引用importimport 的作用域include WXSS尺寸单位样式导入内联样式选择器全局样式与局部样式 WXS注意事项页面渲染数据处理 视图层 View 框架的视图层由 WXML 与 WXSS 编写&#xff0c;由组件来进行…

http库 之 OKHttpUtil

源码位置 方便实用&#xff0c;个人感觉不错 依赖 <dependency><groupId>io.github.admin4j</groupId><artifactId>common-http-starter</artifactId><version>0.7.5</version> </dependency>代码实践 /*** 通用http的pos…

改进YOLO系列:2.添加ShuffleAttention注意力机制

添加ShuffleAttention注意力机制 1. ShuffleAttention注意力机制论文2. ShuffleAttention注意力机制原理3. ShuffleAttention注意力机制的配置3.1common.py配置3.2yolo.py配置3.3yaml文件配置1. ShuffleAttention注意力机制论文 论文题目:SA-NET: SHUFFLE ATTENTION …