当前位置: 首页 > news >正文

Spring监听的使用、原理、源码分析

一、原理分析

        Spring监听的核心原理就是观察者模式。本文将对应观察者模式分析Spring监听的使用和原理。文章较长,跳转记得使用文章右边的目录。

        1.1,观察者模式的组成

1,Subject:目标,即被观察者

        维护了观察者列表;

        提供观察者添加、删除方法;

        通知观察者方法;

        目标发生变化的发放,具体变化业务由子类实现(相当于又使用了抽象模版设计模式)

2,ConcreteSubject:具体目标,即被观察者子类

        实现目标具体变化业务

3,Observer:观察者

        根据目标变化,做出相应的反应。实际业务由子类实现

4,ConcreteObserver:具体观察者

        实现观察者的实际变化业务

        1.2,观察者模式原理

        当被观察者发生变化时,根据维护的观察者列表,在通知观察者方法中,遍历观察者列表依次通知,调用观察者的反应方法。

        2.1,Spring监听组成

1,Event:事件,相当于被观察者。非Spring Bean

        Spring提供了事件基类:ApplicationEvent extends EventObject,用户自定义事件只需继承基类实现自己的数据变化业务即可;

        监听列表(观察者列表)由Spring容器管理;

2,Listener:监听器,相当于观察者。Spring Bean

        Spring提供了监听器基类:

        ApplicationListenner<E extends ApplicationEvent> extends EventListener ,用户自定义监听器需指明监听事件,并实现自己的事件反应业务;

3,Publisher:事件发布器。Spring独有,Spring Bean

        观察者模式中,当目标发生变化后,需要由修改目标变化的线程主动调用目标的通知观察者方法,以此触发观察者的执行;

        Spring监听在事件发生后,由修改事件变化的线程调用Spring容器的事件发布方法,以此触发监听的执行。

        2.2,Spring监听原理

        Spring容器维护了事件-监听的容器:Map<Event, Set<Listener>>。当事件发布后,通过维护的事件-监听容器,找到对应的监听,通过反射,调用监听方法。

        由于事件非Spring Bean,故事件发布前,容器中并不存在事件-监听的关系。由于监听器在声明时已经指明了监听的事件,故在事件发布时,通过Listener Bean与事件作匹配对比,维护在Map容器中。

二、使用方式

        构造了一个最基础的springboot项目用于底座,实现了一个事件多个监听器的Demo,项目结构如下:

        1,定义事件

package com.example.simplespringlistener.events;import org.springframework.context.ApplicationEvent;public class MyEvent extends ApplicationEvent {private String priceChangedStr;public MyEvent(Object source, String priceChangedStr) {super(source);this.priceChangedStr = priceChangedStr;}public String getPriceChangedStr() {return priceChangedStr;}public void setPriceChangedStr(String priceChangedStr) {this.priceChangedStr = priceChangedStr;}
}

        2,定义监听器

 

        定义监听器共有三种方式: 

        2.1,实现基类:ApplicationListner<E extends ApplicationEvent>

package com.example.simplespringlistener.listeners;import com.example.simplespringlistener.events.MyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Service;@Service
public class MyListener1 implements ApplicationListener<MyEvent> {@Overridepublic void onApplicationEvent(MyEvent event) {System.out.println(this.getClass().getName() + " : 监听到事件发生改变。具体事件:" + event.getPriceChangedStr());}}

        实现接口时,指明监听的事件,用于发布时找到事件对应的监听器。 

        2.2,使用注解:@EventListener

package com.example.simplespringlistener.listeners;import com.example.simplespringlistener.events.MyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;@Service
public class MyListener2 {@EventListener(MyEvent.class)public void handlerEvent(MyEvent event) {System.out.println(this.getClass().getName() + " : 监听到事件发生改变。具体事件:" + event.getPriceChangedStr());}}

        使用注解时,指明监听的事件,用于发布时找到事件对应的监听器。如果不指定监听的事件,该监听器将会监听所有事件。Spring在启动时,发布了框架所需要的一批事件,故自定义事件需要与框架定义的事件区分开来。

        2.3,使用注解:@TransactionalEventListener

package com.example.simplespringlistener.listeners;import com.example.simplespringlistener.events.MyEvent;
import org.springframework.stereotype.Service;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;@Service
public class MyListener3 {// 使用默认执行机制时,phase属性可省略@TransactionalEventListener(value = MyEvent.class, phase = TransactionPhase.AFTER_COMPLETION)public void handlerEvent(MyEvent event) {System.out.println(this.getClass().getName() + " : 监听到事件发生改变。具体事件:" + event.getPriceChangedStr());}}

         使用注解时,指明监听的事件,用于发布时找到事件对应的监听器。该注解需要依赖

<artifactId>spring-tx</artifactId>。@EventListener的区别在于:@EventListner无法指明监听器的执行时机。当主线程发布事件后,不管主线程发布后的事务是否提交,@EventListener监听器就开始执行。而@TransactionalEventListener默认在主线程提交事务后执行,还可以通过注解的phase属性调整监听器的执行时机,phase的可选值分别有:

public enum TransactionPhase {/*** 事务提交前*/BEFORE_COMMIT,/*** 事务提交后*/AFTER_COMMIT,/*** 事务回滚后*/AFTER_ROLLBACK,/*** 事务完成后*/AFTER_COMPLETION

        3,定义发布器

package com.example.simplespringlistener.publishers;import com.example.simplespringlistener.events.MyEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;@Service
public class MyPublisher {@Autowiredprivate ApplicationContext applicationContext;public void doPublish(String eventChangeStr) {applicationContext.publishEvent(new MyEvent(this, eventChangeStr));}}

        4,测试Spring监听

package com.example.simplespringlistener.controller;import com.example.simplespringlistener.publishers.MyPublisher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class TestListenerController {@Autowiredprivate MyPublisher myPublisher;@PostMapping(value = "/updatePrice")public void updatePrice(@RequestParam(value = "newPrice") String newPrice) {myPublisher.doPublish(newPrice);}
}

        在业务需要的地方发布事件即可,执行结果如下:

三、源码分析

        根据上面的例子可知,Spring监听的入口在于事件发布,我们就从发布处查看源码

        从后面明显能知道:第一个是实际调用类,第二个是接口,第三个是测试用类。我们进第一类:

        进入该方法

        前面确定广播器类型的方法非核心方法,我们先沿着主流程查看,进入核心事件方法:multicastEvent()

        进入该方法后发现,该方法主要逻辑就是找到事件对应的监听器,然后调用监听。这两个分支都很重要,我们先查看“调用监听器” 的分支源码。

        1,调用监听器源码

        根据上文,监听器的实现有三种方式,每种方式的调用源码路径不同,下面将根据各种方式一一详解。

        1.1,实现基类ApplicationListner源码

1.1.1,调用监听器
1.1.2,调用的中间过程
1.1.3,调用onApplicationEvent()

 

        此时调用listener.onApplicationEvent()方法,该方法已被MyListener1继承并重写,则调用会直接进入MyListener1,执行监听器的方法,结束。

1.1.4,执行监听器方法

        1.2,使用注解@EventListener源码

1.2.1,调用监听器
1.2.2,调用的中间过程
1.2.3,调用onApplicationEvent()

        根据图1.2.1,此处的listener不是MyListener2,而是ApplicationListenerMethodAdapter,使用了适配器设计模式, 在该适配器中,赋值了几个重要属性:监听器Bean(MyListener2)、监听器方法、事件。通过适配器属性,将事件与监听器和具体方法产生关联,再通过反射调用方法。

        上图断点接着往里进入方法,如下图,进到了适配器类中:

1.2.4,进入适配器类

        查看该适配器的属性,如下图: 

1.2.5,查看适配器属性

        查看完属性后,接着图1.2.4往方法里进入,如下图:

1.2.6,处理参数和调用方法

        接着看doInvoke(args)方法,如下图:

1.2.7,调用方法

        获取MyListener2 Bean后,通过反射调用方法,进入到MyListener2的 handlerEvent()

        1.3,使用注解@TransactionalEventListener源码

        源码调用过程与@EventListener一样

        2,获取监听器源码

        看完了调用监听器的源码,知道了源码是怎么执行到自定义监听器的方法里了。接下来看源码的另一个分支:如何根据事件,找到对应的监听器?分支起点如下:

        这次源码要查看的方法是for循环里的getApplicationListeners(event, type),如下图:

        由上图可见,该方法的返回值是监听器集合,整体思路也很简单:

        步骤一:从 retrieverCache 中获取结果。retrieverCache 是个Map集合,map-key是类 ListenerCacheKey(该类包含了具体事件属性、发布器属性),map-value是类 CachedListenerRetriever(该类包含了监听器集合、监听器Bean名称集合),如下图:

        步骤二:如果map-value存在,就返回CachedListenerRetriever的监听器集合;

        步骤三:如果map-value不存在,创建CachedListenerRetriever 作为map-value放入retrieverCache map中,并在下面通过 retrieveApplicationListeners(eventType, sourceType, newRetriever) 方法 为新建的map-value赋予上图两个集合属性。最后返回该map-value即可。

        第一次发布事件时,retrieverCache map中没有事件对应的监听器集合,需要执行步骤三,接着查看步骤三方法源码,如下图:

        前面第一步原理分析中已经说明,每个监听器都是SpringBean,即for循环中的listeners包含了Spring启动时的所有监听器,如下图:

        接着查看源码是如何匹配事件-监听的,进入方法supports(listener, eventType, sourceType),如下图:

        又是适配器模式,通过适配器,最终通过this.declaredEventType.isAssignableFrom(eventType)) 判断是否匹配。即,根据监听器声明时指定的事件类型,与当前传入的事件class 做对比,监听器指定的事件如果是当前传入的事件的本类或子类,则表明当前监听器监听了当前事件。

        至此,Spring监听的源码已分析完毕,请再回头看看第一节的Spring监听原理分析,整个流程就非常清晰且简单了。

相关文章:

Spring监听的使用、原理、源码分析

一、原理分析 Spring监听的核心原理就是观察者模式。本文将对应观察者模式分析Spring监听的使用和原理。文章较长&#xff0c;跳转记得使用文章右边的目录。 1.1&#xff0c;观察者模式的组成 1&#xff0c;Subject&#xff1a;目标&#xff0c;即被观察者 维护了观察者列表&am…...

CSS布局学习2

flex布局中span会改变行为 在使用 Flex 布局时&#xff0c;盒子中的子元素&#xff08;如 span&#xff09;会自动成为 Flex 项目&#xff0c;并参与 Flex 布局的计算。具体原因如下&#xff1a; Flex 容器&#xff1a;当一个元素设置为 display: flex; 时&#xff0c;它会变…...

Oracle - 多区间按权重取值逻辑 ,分时区-多层级-取配置方案(三)

本篇紧跟第一篇&#xff0c; 和 第二篇无关 Oracle - 多区间按权重取值逻辑 &#xff0c;分时区-多层级-取配置方案 Oracle - 多区间按权重取值逻辑 &#xff0c;分时区-多层级-取配置方案(二) 先说需求&#xff1a; 某业务配置表&#xff0c;按配置的时间区间及组织层级取方…...

Spring Cloud Netflix 系列:Eureka 经典实战案例和底层原理解析

文章目录 前言Eureka 简介架构设计工作流程 项目 demo 构建Eureka Server 的搭建Eureka Client 的配置补充说明 运行效果 深入使用Eureka 注册中心添加认证搭建 Eureka 集群实现高可用双节点集群搭建 运行效果补充说明为什么要配置 不同host 原理解析服务注册、心跳续期详细流程…...

ElasticSearch学习篇17_《检索技术核心20讲》最邻近检索-局部敏感哈希、乘积量化PQ思路

目录 场景在搜索引擎和推荐引擎中&#xff0c;对相似文章去重是一个非常重要的环节&#xff0c;另外是拍照识花、摇一摇搜歌等场景都可以使用它快速检索。 基于敏感性哈希的检索更擅长处理字面上的相似而不是语义上的相似。 向量空间模型ANN检索加速思路 局部敏感哈希编码 随…...

2024亚太杯国际赛C题参考文章50页+完整解题思路+数据处理+最终结果

中国宠物食品行业的发展趋势与汇率情景分析&#xff1a;基于多模型的量化预测与决策分析 一 、 摘要 本文针对宠物产业及相关产业的发展分析问题&#xff0c;采用多种数学建模方法和数据 分析技术&#xff0c;构建了一系列预测和评估模型。从宠物数量预测、全球市场分析、产业 …...

推荐几个 VSCode 流程图工具

Visual Studio Code&#xff08;简称VSCode&#xff09;是一个由微软开发的免费、开源的代码编辑器。 VSCode 发布于 2015 年&#xff0c;而且很快就成为开发者社区中广受欢迎的开发工具。 VSCode 可用于 Windows、macOS 和 Linux 等操作系统。 VSCode 拥有一个庞大的扩展市…...

渗透测试笔记——shodan(4)

声明&#xff1a; 学习视频来自B站up主 【泷羽sec】有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&am…...

一次封装,解放双手:Requests如何实现0入侵请求与响应的智能加解密

引言 之前写了 Requests 自动重试的文章&#xff0c;突然想到&#xff0c;之前还用到过 Requests 自动加解密请求的逻辑&#xff0c;分享一下。之前在做逆向的时候&#xff0c;发现一般医院的小程序请求会这么玩&#xff0c;请求数据可能加密也可能不加密&#xff0c;但是返回…...

c++中操作数据库的常用函数

在C中操作数据库&#xff0c;尤其是MySQL数据库&#xff0c;主要通过MySQL提供的C API或MySQL Connector/C库来实现。这些库提供了一系列的函数&#xff0c;使得开发者能够在C应用程序中执行数据库的连接、查询、更新、删除等操作。以下是C中操作MySQL数据库的一些常用函数&…...

CoAP 协议介绍:特性、应用与优劣势

CoAP 协议简介 CoAP 协议&#xff08;Constrained Application Protocol&#xff09;是一种专门为受限设备设计的互联网应用协议。它旨在让小型、低功耗的设备能够接入物联网&#xff08;IoT&#xff09;。该协议允许这些设备以最小的资源与更广泛的互联网进行通信。 CoAP 协…...

leetcode hot100【LeetCode 53.最大子数组和】java实现

LeetCode 53.最大子数组和 题目描述 给定一个整数数组 nums&#xff0c;找到一个具有最大和的连续子数组&#xff08;至少一个元素&#xff09;&#xff0c;返回其最大和。 子数组是数组中的一个连续部分。 示例 1: 输入: nums [-2,1,-3,4,-1,2,1,-5,4] 输出: 6 解释: 连续…...

MAC C语言 Helloword

在 macOS 系统上编写并运行一个简单的 “Hello, World!” 程序&#xff0c;你可以使用多种编程语言。下面我将以 C 语言为例&#xff0c;展示如何在 macOS 上编写、编译和运行这个经典的 “Hello, World!” 程序。 步骤 1: 安装 Xcode Command Line Tools macOS 系统上通常没…...

【过程控制系统】第6章 串级控制系统

目录 6. l 串级控制系统的概念 6.1.2 串级控制系统的组成 6.l.3 串级控制系统的工作过程 6.2 串级控制系统的分析 6.2.1 增强系统的抗干扰能力 6.2.2 改善对象的动态特性 6.2.3 对负荷变化有一定的自适应能力 6.3 串级控制系统的设计 6.3.1 副回路的选择 2.串级系…...

springboot:责任链模式实现多级校验

责任链模式是将链中的每一个节点看作是一个对象&#xff0c;每个节点处理的请求不同&#xff0c;且内部自动维护一个下一节点对象。 当一个请求从链式的首段发出时&#xff0c;会沿着链的路径依此传递给每一个节点对象&#xff0c;直至有对象处理这个请求为止。 属于行为型模式…...

如何构建高效的接口自动化测试框架?

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 在选择接口测试自动化框架时&#xff0c;需要根据团队的技术栈和项目需求来综合考虑。对于测试团队来说&#xff0c;使用Python相关的测试框架更为便捷。无论选…...

spring-logback引用外部文件

背景 在spring微服务开发和云部署中&#xff0c;都涉及到日志的收集&#xff0c;很多时候为例方便管理和开发&#xff0c;很多公司都会开发一些基础配置代码。其中日志就是很重要的部分&#xff0c; 为了方便部署、收集、查看&#xff0c;所以日志文件需要存储在同一个…...

【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段

文章目录 一、MyBatis-Plus简介二、快速入门1、环境准备2、将mybatis项目改造成mybatis-plus项目&#xff08;1&#xff09;引入MybatisPlus依赖&#xff0c;代替MyBatis依赖&#xff08;2&#xff09;配置Mapper包扫描路径&#xff08;3&#xff09;定义Mapper接口并继承BaseM…...

go项目中比较好的实践方案

工作两年来&#xff0c;我并未遇到太大的挑战&#xff0c;也没有特别值得夸耀的项目。尽管如此&#xff0c;在日常的杂项工作中&#xff0c;我积累了不少心得&#xff0c;许多实践方法也在思考中逐渐得到优化。因此&#xff0c;我在这里记录下这些心得。 转发与封装 这个需求…...

Windows之使用putty软件以ssh的方式连接Linux中文显示乱码

项目场景&#xff1a; 运行环境&#xff1a;Windows10 使用软件&#xff1a;putty 操作说明&#xff1a;以ssh的方式连接Linux 中文显示乱码 问题描述 Windows之使用putty软件以ssh的方式连接Linux中文显示乱码 原因分析&#xff1a; linux 机器的系统语言字符集与putty软件…...

springboot整合hive

springboot整合hive pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.…...

vxe-form table 修改表单数据校验的主题样式

在使用 vxe-form 表单校验时&#xff0c;数据校验可以支持2种主题样式 官网&#xff1a;https://vxeui.com 普通样式 通过设置 valid-config.theme‘normal’ 设置为普通样式 高亮样式 通过设置 valid-config.theme‘beautify’ 设置为高亮样式 <template><div&…...

【UE5】使用基元数据对材质传参,从而避免新建材质实例

在项目中&#xff0c;经常会遇到这样的需求&#xff1a;多个模型&#xff08;例如 100 个&#xff09;使用相同的材质&#xff0c;但每个模型需要不同的参数设置&#xff0c;比如不同的颜色或随机种子等。 在这种情况下&#xff0c;创建 100 个实例材质不是最佳选择。正确的做…...

一个计算频率的模块

先上代码 module _sync_reg #(parameter INIT 0,parameter ASYNC_RESET 0 ) (input clk,input rst,input in,output out );(* ASYNC_REG "TRUE" *) reg sync1; (* ASYNC_REG "TRUE" *) reg sync2;assign out sync2;generate if (ASYNC_RE…...

在SpringBoot项目中集成MongoDB

文章目录 1. 准备工作2. 在SpringBoot项目中集成MongoDB2.1 引入依赖2.2 编写配置文件2.3 实体类 3. 测试4. 文档操作4.1 插入操作4.1.1 单次插入4.1.2 批量插入 4.2 查询操作4.2.1 根据id查询4.2.2 根据特定条件查询4.2.3 正则查询4.2.4 查询所有文档4.2.5 排序后返回 4.3 删除…...

OpenJudge - 24:输出保留3位小数的浮点数

【题目来源】http://shnoip.openjudge.cn/level1/24/【题目描述】 读入一个单精度浮点数&#xff0c;保留3位小数输出这个浮点数。【输入格式】 只有一行&#xff0c;一个单精度浮点数。【输出格式】 也只有一行&#xff0c;读入的单精度浮点数。【输入样例】 12.34521【输出样…...

华为流程L1-L6业务流程深度细化到可执行

该文档主要介绍了华为业务流程的深度细化及相关内容,包括流程框架、建模方法、流程模块描述、流程图建模等,旨在帮助企业构建有效的流程体系,实现战略目标。具体内容如下: 华为业务流程的深度细化 流程层级:华为业务流程分为 L1 - L6 六个层级,L1 为流程大类,L2 为流程…...

Python中Tushare(金融数据库)入门详解

文章目录 Python中Tushare&#xff08;金融数据库&#xff09;入门详解一、引言二、安装与注册1、安装Tushare2、注册与获取Token 三、Tushare基本使用1、设置Token2、获取数据2.1、获取股票基础信息2.2、获取交易日历2.3、获取A股日线行情2.4、获取沪股通和深股通成份股2.5、获…...

Odoo中,要实现实时数据推送,SSE 与 WebSocket 该如何选择

目录 1. 技术特点对比 2. 使用场景 适合使用 SSE 的场景&#xff1a; 适合使用 WebSocket 的场景&#xff1a; 3. 优缺点总结 SSE 优点&#xff1a; SSE 缺点&#xff1a; WebSocket 优点&#xff1a; WebSocket 缺点&#xff1a; 4. 选择建议 选择 SSE 的条件&#x…...

02. Python基础知识

一、注释 在开发程序过程中&#xff0c;如果一段代码的逻辑比较复杂&#xff0c;不是特别容易理解&#xff0c;可以适当添加注释&#xff0c;以辅助自己或其他开发人员解读代码。注释是给程序员看的&#xff0c;为了让程序员方便阅读代码&#xff0c;解释器会忽略注释。在 Pyto…...

Mac 修改默认jdk版本

当前会话生效 这里演示将 Java 17 版本降低到 Java 8 查看已安装的 Java 版本&#xff1a; 在终端&#xff08;Terminal&#xff09;中运行以下命令&#xff0c;查看已安装的 Java 版本列表 /usr/libexec/java_home -V设置默认 Java 版本&#xff1a; 找到 Java 8 的安装路…...

数字赋能,气象引领 | 气象景观数字化服务平台重塑京城旅游生态

在数字化转型的浪潮中&#xff0c;旅游行业正以前所未有的速度重塑自身&#xff0c;人民群众对于高品质、个性化旅游服务需求的日益增长&#xff0c;迎着新时代的挑战与机遇&#xff0c;为开展北京地区特色气象景观预报&#xff0c;打造“生态气象旅游”新业态&#xff0c;助推…...

C语言项⽬实践-贪吃蛇

目录 1.项目要点 2.窗口设置 2.1mode命令 2.2title命令 2.3system函数 2.Win32 API 2.1 COORD 2.2 GetStdHandle 2.3 CONSOLE_CURSOR_INFO 2.4 GetConsoleCursorInfo 2.5 SetConsoleCursorInfo 2.5 SetConsoleCursorPosition 2.7 GetAsyncKeyState 3.贪吃蛇游戏设…...

springboot整合kafka

springboot整合kafka pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven…...

量子计算机全面解析:技术、应用与未来

标题&#xff1a;量子计算机全面解析&#xff1a;技术、应用与未来 一、什么是量子计算机&#xff1f; 量子计算机是一种利用量子力学原理&#xff08;如叠加、纠缠和干涉&#xff09;进行计算的新型计算设备。与传统计算机基于比特&#xff08;0 和 1&#xff09;的运算方式不…...

提升软件测试报告的质量:Allure2中添加用例失败截图、日志、HTML块和视频的方法

Allure2的用途 Allure2是一个用于生成测试报告的框架&#xff0c;广泛应用于自动化测试和手动测试中。它支持多种测试框架&#xff0c;如JUnit、TestNG、MSTest等&#xff0c;通过生动的图表和详细的日志&#xff0c;使得非技术人员也能轻松地理解测试结果。许多团队选用Allur…...

Mysql启动报错:本地计算机上的mysql服务启动后停止,某些服务在未由其他服务或程序使用时将自动停止

原因 是手动去改了mysql的配置文件my.ini的内容&#xff0c;重新启动服务启动不了。 看了很多文章最终找到了恢复数据的办法。 第一步备份 先备份mysql数据存的文件夹Data&#xff0c;如果找不到则去看配置文件那一行datadir 第二步重新安装mysql 卸载篇可以看我之前发的文…...

国际环境和背景下的云计算领域

前言 在当前国际环境和背景下&#xff0c;云计算领域呈现出复杂多变的局面&#xff0c;其发展深受技术创新、地缘政治、全球经济以及监管政策的影响。以下从技术趋势、市场竞争、地缘政治和监管环境四个方面详细解析云计算领域的现状。 一、技术趋势&#xff1a;多云与边缘计算…...

网络安全-企业环境渗透2-wordpress任意文件读FFmpeg任意文件读

一、 实验名称 企业环境渗透2 二、 实验目的 【实验描述】 操作机的操作系统是kali 进入系统后默认是命令行界面 输入startx命令即可打开图形界面。 所有需要用到的信息和工具都放在了/home/Hack 目录下。 本实验的任务是通过外网的两个主机通过代理渗透到内网的两个主机。…...

C# 超链接控件LinkLabel无法触发Alt快捷键

在C#中&#xff0c;为控件添加快捷键的方式有两种&#xff0c;其中一种就是Windows中较为常见的Alt快捷键&#xff0c;比如运行对话框&#xff0c;记事本菜单等。只需要按下 Alt 框号中带下划线的字母即可触发该控件的点击操作。如图所示 在C#开发中&#xff0c;实现类似的操作…...

一分钟学习数据安全——数据安全风险的系统化应对思路

数据是组织的重要资产&#xff0c;未经授权的数据访问可能导致数据泄露、数据篡改、隐私侵犯和合规风险等问题。企业可以通过数据访问控制来提高信息系统在数据全生命周期管理中的安全性。企业可以引入IAM系统&#xff0c;来控制身份来管理权限。通过对用户访问权限的管理和合适…...

深入了解 Spring Security 的授权核心功能

Spring Security 是一个强大且灵活的安全框架&#xff0c;能够帮助开发者为 Spring 应用程序提供认证和授权服务。在实际应用中&#xff0c;Spring Security 主要涉及用户的认证&#xff08;谁是用户&#xff09;和授权&#xff08;用户能做什么&#xff09;。本文将深入讲解 S…...

【Web前端】创建我的第一个 Web 表单

Web 开发中&#xff0c;表单是不可或缺的组成部分。无论是用户注册、登录还是反馈收集&#xff0c;表单都是与用户交互的重要方式。 什么是 Web 表单&#xff1f; Web 表单是一种用于收集用户输入数据的界面元素。它们允许用户在浏览器中输入信息并提交这些信息到服务器。Web …...

“人工智能+高职”:VR虚拟仿真实训室的发展前景

在当今科技日新月异的时代&#xff0c;人工智能&#xff08;AI&#xff09;与虚拟现实&#xff08;VR&#xff09;技术的融合正逐步改变着各行各业&#xff0c;教育领域也不例外。特别是在高等职业教育&#xff08;简称“高职”&#xff09;体系中&#xff0c;VR虚拟仿真实训室…...

状态模式之状态机

状态机的背景 在软件开发过程中&#xff0c;尤其是涉及到复杂的系统行为控制时&#xff0c;我们常常会遇到这样的情况&#xff1a;一个对象或者系统会在多种状态之间进行转换&#xff0c;并且在不同状态下对相同事件的响应是不同的。 以自动售卖机为例&#xff0c;自动售卖机…...

NUXT3学习日记四(路由中间件、导航守卫)

前言 在 Nuxt 3 中&#xff0c;中间件&#xff08;Middleware&#xff09;是用于在页面渲染之前或导航发生之前执行的函数。它们允许你在路由切换时执行逻辑&#xff0c;像是身份验证、重定向、权限控制、数据预加载等任务。中间件可以被全局使用&#xff0c;也可以只在特定页…...

基于重复控制补偿的高精度 PID 控制

1. 背景与原理 重复控制&#xff08;Repetitive Control, RC&#xff09;是一种适用于周期性信号跟踪和周期性扰动抑制的控制方法&#xff0c;通过在控制回路中引入周期补偿器来提高系统的控制精度。将 RC 与 PID 控制相结合&#xff0c;利用 PID 的快速响应特性和 RC 的周期补…...

Linux之日志

日志 在编写网络服务器, 各种软件时, 程序一定要打印一些日志信息. 1. 可以向显示器打印, 也可以向文件中写入. 2. 日志是软件在运行时记录的流水账, 用于排查服务进程挂掉的信息. 其中必须要有的是: 日志等级, 时间, 日志内容.可选的是文件名, 代码行数, 进程pid 等 日志…...

【LeetCode面试150】——202快乐数

博客昵称&#xff1a;沈小农学编程 作者简介&#xff1a;一名在读硕士&#xff0c;定期更新相关算法面试题&#xff0c;欢迎关注小弟&#xff01; PS&#xff1a;哈喽&#xff01;各位CSDN的uu们&#xff0c;我是你的小弟沈小农&#xff0c;希望我的文章能帮助到你。欢迎大家在…...

云原生之k8s服务管理

文章目录 服务管理Service服务原理ClusterIP服务 对外发布应用服务类型NodePort服务Ingress安装配置Ingress规则 Dashboard概述 认证和授权ServiceAccount用户概述创建ServiceAccount 权限管理角色与授权 服务管理 Service 服务原理 容器化带来的问题 自动调度&#xff1a;…...