RabbitMQ中交换机的应用 ,原理 ,案例的实现

                                🎉🎉欢迎来到我的CSDN主页!🎉🎉

                    🏅我是平顶山大师,一个在CSDN分享笔记的博主。📚📚

    🌟推荐给大家我的博客专栏《RabbitMQ中交换机的应用及原理,案例的实现》。🎯🎯

                    🎁如果感觉还不错的话请给我关注加三连吧!🎁🎁

目录

一、RabbitMQ中交换机的介绍

1.基本概念

1.1. 概述

1.2.RabbitMQ交换机类型

2. 作用及优势

2.1 作用

 2.2 优势

3. 工作原理

二、交换机Exchange

1. Direct 

2. Topic

3. Fanout

三、代码案例

1. 直连direct 

生产者代码

消费者代码:

直连测试:

2.Topic

生产者代码

测试

3. 扇形fanout 

生产者代码

测试

总结:


一、RabbitMQ中交换机的介绍

1.基本概念


1.1. 概述

RabbitMQ中的交换机(exchange)是消息的分发中心,它接收来自生产者的消息,并将这些消息路由到一个或多个队列中。交换机根据消息的路由键(routing key)将消息发送到相应的队列中。

1.2.RabbitMQ交换机类型

RabbitMQ一共四种交换机,如下所示:

直连交换机(direct exchange):直连交换机根据消息的路由键将消息发送到与之匹配的队列中。如果消息的路由键与队列的绑定键(binding key)完全匹配,那么消息将被发送到该队列中。

主题交换机(topic exchange):主题交换机根据消息的路由键和队列的绑定键的模式进行匹配。可以使用通配符(*和#)来匹配多个路由键,从而实现更灵活的消息路由。符号#表示一个或多个词,*表示一个词。

扇形交换机(fanout exchange):扇出交换机将消息发送到所有与之绑定的队列中,无论消息的路由键是什么。它实现了一对多的消息分发。

头部交换机(headers exchange):头部交换机根据消息的头部信息进行匹配,而不是路由键。可以根据消息的头部属性来决定消息的路由。

交换机和队列之间通过绑定(binding)进行关联,生产者将消息发送到交换机,交换机根据路由键将消息发送到相应的队列中。交换机和队列的绑定关系可以通过管理界面或者命令行工具进行配置。交换机它负责将消息路由到相应的队列中,实现了灵活的消息分发机制。不同类型的交换机可以满足不同的业务需求,开发者可以根据实际情况选择合适的交换机类型来实现消息的路由和分发。

2. 作用及优势


2.1 作用

交换机在项目中的主要作用包括:

       1. 消息路由:交换机负责将消息路由到一个或多个队列中,根据消息的路由键和交换机的类型进行匹配和分发,确保消息能够准确地到达目标队列。

       2. 消息分发:交换机可以根据不同的规则将消息分发到不同的队列中,实现灵活的消息分发机制。这对于实现消息的多播、广播等场景非常有用。

       3. 解耦:通过交换机,生产者和消费者之间可以完全解耦,生产者只需要将消息发送到交换机中,而不需要关心消息具体发送到哪个队列中,消费者也只需要从队列中接收消息,而不需要关心消息的来源。

        4. 消息过滤:通过不同类型的交换机和绑定规则,可以实现消息的过滤和选择性接收,确保消费者只接收到其关心的消息。

        5. 实现消息通道:交换机是消息在RabbitMQ中的通道,通过交换机可以将消息从生产者传递给消费者,实现了消息的传递和通信。

交换机在项目中起到了消息路由、分发、解耦和过滤等重要作用,是实现消息传递和通信的关键组件。通过合理使用不同类型的交换机,可以实现灵活、高效的消息传递机制,满足不同业务场景的需求。

 2.2 优势

交换机在消息传递系统中具有以下优势:

        1. 灵活的消息路由:交换机可以根据消息的路由键将消息发送到不同的队列中,实现了灵活的消息路由机制。这样可以根据消息的不同属性将消息发送到不同的消费者或处理逻辑中,提高了系统的灵活性和可扩展性。

        2. 解耦和分布式系统支持:通过交换机,生产者和消费者之间可以完全解耦,生产者只需要将消息发送到交换机中,而不需要关心消息具体发送到哪个队列中,消费者也只需要从队列中接收消息,而不需要关心消息的来源。这对于构建分布式系统和微服务架构非常有用。

        3. 多播和广播支持:通过扇出交换机(fanout exchange),交换机可以将消息发送到所有与之绑定的队列中,实现了一对多的消息分发,支持了多播和广播的消息传递方式。

        4. 消息过滤和选择性接收:通过不同类型的交换机和绑定规则,可以实现消息的过滤和选择性接收,确保消费者只接收到其关心的消息,提高了系统的效率和性能。

        5. 实现消息通道:交换机是消息在消息队列系统中的通道,通过交换机可以将消息从生产者传递给消费者,实现了消息的传递和通信,为系统中的消息传递提供了可靠的通道。

总的来说,交换机在消息传递系统中具有灵活的消息路由、解耦和分布式系统支持、多播和广播支持、消息过滤和选择性接收等优势,为构建高效、灵活的消息传递系统提供了重要的支持。        

3. 工作原理

RabbitMQ的交换机(Exchange)是消息路由的核心组件,负责消息的分发和路由。下面是RabbitMQ交换机的工作原理:

       1. 发布消息:生产者将消息发送到RabbitMQ的交换机中,同时指定一个路由键(Routing Key)。

       2. 交换机根据类型进行路由:RabbitMQ的交换机有四种类型,分别是直连交换机(direct exchange)、扇出交换机(fanout exchange)、主题交换机(topic exchange)和头部交换机(headers exchange)。不同类型的交换机根据不同的路由规则进行消息的路由和分发。

       3. 路由规则:直连交换机根据消息的路由键将消息发送到与之绑定的队列中;扇出交换机将消息发送到所有与之绑定的队列中;主题交换机根据消息的路由键和队列的绑定规则进行匹配,将消息发送到匹配的队列中;头部交换机根据消息的头部属性进行匹配,将消息发送到匹配的队列中。

       4. 绑定队列:交换机需要和队列进行绑定,指定绑定的路由键或者其他条件,确保消息能够被正确地路由到目标队列中。

       5. 发送到队列:一旦消息被交换机路由到目标队列,消费者就可以从队列中接收并处理消息。

总的来说,RabbitMQ的交换机根据不同的类型和路由规则,将消息发送到目标队列中,实现了消息的路由和分发。通过合理使用不同类型的交换机和绑定规则,可以实现灵活、高效的消息传递机制,满足不同业务场景的需求。

二、交换机Exchange


1. Direct 

 直连交换机(Direct Exchange)是RabbitMQ中最简单的交换机类型之一,它使用消息的路由键(Routing Key)来决定将消息发送到哪个队列。

 

2. Topic


主题交换机(Topic Exchange)是RabbitMQ中一种灵活且强大的交换机类型,它使用消息的路由键和通配符模式来决定将消息发送到哪个队列。Queue 通过 routingkey 绑定到TopicExchange 上,当消息到达 TopicExchange 后,TopicExchange 根据消息的 routingkey 将消息路由到一个或者多个 Queue 上。

3. Fanout


扇形交换机是RabbitMQ中的一种消息路由方式,FanoutExchange 的数据交换策略是把所有到达 FanoutExchange 的消息转发给所有与它绑定的 Queue 上,在这种策略中,routingkey 将不起任何作用,不管消息的路由键是什么。

进入RabbitMQ的管理页面:

这里会展示交换机的各种信息:

Type 表示交换机的类型。

Features 有两个取值 D 和 I。

D 表示交换机持久化,将交换机的属性在服务器内部保存,当 MQ 的服务器发生意外或关闭之后,重启 RabbitMQ 时不需要重新手动或执行代码去建立交换机,交换机会自动建立,相当于一直存在。

I 表示这个交换机不可以被消息生产者用来推送消息,仅用来进行交换机和交换机之间的绑定。

Message rate in 表示消息进入的速率。 Message rate out 表示消息出去的速率。

点击下方的 Add a new exchange 可以创建一个新的交换机。

三、代码案例

如果你掌握了上一篇博客的基础上,再来写这一次的案例,就是soeasy

3.1开启docker服务

登录:

1. 直连direct 

生产者代码

        在生产者项目中的RabbitConfig中增加以下代码:

 /*** 直连交换机* /* 创建两个Binding Bean,分别与Queue01和Queue02队列进行绑定* 并都指向directExchange01(直连交换机),键分别为Key01和Key02*///  创建队列@Beanpublic Queue Queue01() {return new Queue("Queue01");}@Beanpublic Queue Queue02() {return new Queue("Queue02");}// 创建直连(direct)交换机@Beanpublic DirectExchange directExchange01() {return new DirectExchange("directExchange01");}// 创建Binding Bean,与Queue01和directExchange01绑定,键为Key01@Beanpublic Binding binding01() {return BindingBuilder.bind(Queue01()).to(directExchange01()).with("Key01");}// 创建Binding Bean,与Queue02和directExchange01绑定,键为Key02@Beanpublic Binding binding02() {return BindingBuilder.bind(Queue02()).to(directExchange01()).with("Key02");}

        在生产者项目中的TestController中增加以下代码:

//    -------------------------直连------------------------------------@RequestMapping("sender3")@ResponseBodypublic String sender3() {// 发送消息到名为directExchange01的交换机,路由键为key01,信息内容为:Hello, direct exchange!// 这里的directExchange01是RabbitMQ中定义的交换机名称// 这里的key01是RabbitMQ中定义的路由键名称rabbitTemplate.convertAndSend("directExchange01","Key01", "Hello, direct exchange!");return "👍3";}@RequestMapping("sender4")@ResponseBodypublic String sender4() {// 发送消息到名为directExchange01的交换机,路由键为key02,信息内容为:Hello, direct exchange!// 这里的directExchange01是RabbitMQ中定义的交换机名称// 这里的key02是RabbitMQ中定义的路由键名称rabbitTemplate.convertAndSend("directExchange01","Key02", "Hello, direct exchange!");return "😘4";}

消费者代码:

        ReceiverQ1接收交换机中Queue01队列消息的方法:

package com.example.consumer;import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;@Component
@SuppressWarnings("all")
@Slf4j
@RabbitListener(queues = "Queue01")
public class ReceiverQ1 {// 接收directExchange01交换机中Queue01队列消息的方法@RabbitHandlerpublic void Queue01(String msg) {log.warn("Queue01,接收到信息:" + msg);}}

        ReceiverQ2接收交换机中Queue02队列消息的方法

package com.example.consumer;import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;@Component
@SuppressWarnings("all")
@Slf4j
@RabbitListener(queues = "Queue02")
public class ReceiverQ2 {// 接收directExchange01交换机中Queue02队列消息的方法@RabbitHandlerpublic void Queue02(String msg) {log.warn("Queue02,接收到信息:" + msg);}}

这里在备注一下;生产者根据key来找对应的消息队列

直连测试:


 

2.Topic

生产者代码

        RabbitConfig中增加以下代码:

 /*** 主题交换机**  '*'代表一个单词,*  '#'代表任意数量的字符,也代表0个或多个*/// 创建主题交换机@Beanpublic TopicExchange topicExchange() {return new TopicExchange("topicExchange");}@Beanpublic Binding binding03() {return BindingBuilder.bind(Queue01()).to(topicExchange()).with("*.*.Q1");}@Beanpublic Binding binding04() {return BindingBuilder.bind(Queue02()).to(topicExchange()).with("*.*.Q2");}@Beanpublic Binding binding05() {return BindingBuilder.bind(Queue01()).to(topicExchange()).with("平顶山大师.#");}@Beanpublic Binding binding06() {return BindingBuilder.bind(Queue02()).to(topicExchange()).with("平顶山大师.#");}

        TestController中增加以下代码:

 //    -------------------------主题topic ------------------------------------@RequestMapping("sender5")@ResponseBodypublic String test05(String rex) {rabbitTemplate.convertAndSend("topicExchange",rex,"Hello,topicExchange:Queue!");return "🎈5";}@RequestMapping("sender6")@ResponseBodypublic String test06() {rabbitTemplate.convertAndSend("fanoutExchange","","Hello,fanoutExchange:Queue!");return "💕6";}

测试

3. 扇形fanout 

生产者代码

RabbitConfig中增加以下代码:

    /*** 扇形交换机** 定义了一个FanoutExchange,加上Bean注解* 定义了两个Binding,加上Bean注解* 将两个队列绑定到FanoutExchange上,从而实现广播消息的功能* 扇形交换机会将接收到的消息路由到所有绑定到它上的队列。*/// 创建扇形交换机@Beanpublic FanoutExchange fanoutExchange() {return new FanoutExchange("fanoutExchange");}@Beanpublic Binding binding07() {return BindingBuilder.bind(Queue01()).to(fanoutExchange());}@Beanpublic Binding binding08() {return BindingBuilder.bind(Queue02()).to(fanoutExchange());}

TestController中增加以下代码:

    @RequestMapping("sender6")@ResponseBodypublic String test06() {rabbitTemplate.convertAndSend("fanoutExchange","","Hello,fanoutExchange:Queue!");return "💕6";}

这里会直接发送到Q1,Q2

测试

全部代码:

RabbitConfig:

package com.example.provide;import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
@SuppressWarnings("all")
public class RabbitConfig {@Beanpublic Queue firstQueue() {return new Queue("firstQueue");}@Beanpublic Queue secondQueue() {return new Queue("secondQueue");}//   RabbitConfigII/*** 直连交换机* /* 创建两个Binding Bean,分别与Queue01和Queue02队列进行绑定* 并都指向directExchange01(直连交换机),键分别为Key01和Key02*///  创建队列@Beanpublic Queue Queue01() {return new Queue("Queue01");}@Beanpublic Queue Queue02() {return new Queue("Queue02");}// 创建直连(direct)交换机@Beanpublic DirectExchange directExchange01() {return new DirectExchange("directExchange01");}// 创建Binding Bean,与Queue01和directExchange01绑定,键为Key01@Beanpublic Binding binding01() {return BindingBuilder.bind(Queue01()).to(directExchange01()).with("Key01");}// 创建Binding Bean,与Queue02和directExchange01绑定,键为Key02@Beanpublic Binding binding02() {return BindingBuilder.bind(Queue02()).to(directExchange01()).with("Key02");}/*** 主题交换机**  '*'代表一个单词,*  '#'代表任意数量的字符,也代表0个或多个*/// 创建主题交换机@Beanpublic TopicExchange topicExchange() {return new TopicExchange("topicExchange");}@Beanpublic Binding binding03() {return BindingBuilder.bind(Queue01()).to(topicExchange()).with("*.*.Q1");}@Beanpublic Binding binding04() {return BindingBuilder.bind(Queue02()).to(topicExchange()).with("*.*.Q2");}@Beanpublic Binding binding05() {return BindingBuilder.bind(Queue01()).to(topicExchange()).with("平顶山大师.#");}@Beanpublic Binding binding06() {return BindingBuilder.bind(Queue02()).to(topicExchange()).with("平顶山大师.#");}/*** 扇形交换机** 定义了一个FanoutExchange,加上Bean注解* 定义了两个Binding,加上Bean注解* 将两个队列绑定到FanoutExchange上,从而实现广播消息的功能* 扇形交换机会将接收到的消息路由到所有绑定到它上的队列。*/// 创建扇形交换机@Beanpublic FanoutExchange fanoutExchange() {return new FanoutExchange("fanoutExchange");}@Beanpublic Binding binding07() {return BindingBuilder.bind(Queue01()).to(fanoutExchange());}@Beanpublic Binding binding08() {return BindingBuilder.bind(Queue02()).to(fanoutExchange());}
}

TestController:

package com.example.provide;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;/*** @author 程序猿-小李哥* @site www.xiaolige.com* @company 猪八戒有限集团* @create 2024-01-19-18:46*/
@Controller
public class Testcontrol {@Autowiredprivate AmqpTemplate rabbitTemplate;@Autowiredprivate ObjectMapper objectMapper;@RequestMapping("/sender1")@ResponseBodypublic String sendFirst() {rabbitTemplate.convertAndSend("firstQueue", "Hello World");return "😶‍🌫️1";}@RequestMapping("/sender2")@ResponseBodypublic String sender2() throws JsonProcessingException {User user = new User("1", "1");// 序列化对象转换为JSON字符串String json = objectMapper.writeValueAsString(user);rabbitTemplate.convertAndSend("secondQueue", json);return "😎2";}//    -------------------------直连------------------------------------@RequestMapping("sender3")@ResponseBodypublic String sender3() {// 发送消息到名为directExchange01的交换机,路由键为key01,信息内容为:Hello, direct exchange!// 这里的directExchange01是RabbitMQ中定义的交换机名称// 这里的key01是RabbitMQ中定义的路由键名称rabbitTemplate.convertAndSend("directExchange01","Key01", "Hello, direct exchange!");return "👍3";}@RequestMapping("sender4")@ResponseBodypublic String sender4() {// 发送消息到名为directExchange01的交换机,路由键为key02,信息内容为:Hello, direct exchange!// 这里的directExchange01是RabbitMQ中定义的交换机名称// 这里的key02是RabbitMQ中定义的路由键名称rabbitTemplate.convertAndSend("directExchange01","Key02", "Hello, direct exchange!");return "😘4";}//    -------------------------主题topic ------------------------------------@RequestMapping("sender5")@ResponseBodypublic String test05(String rex) {rabbitTemplate.convertAndSend("topicExchange",rex,"Hello,topicExchange:Queue!");return "🎈5";}@RequestMapping("sender6")@ResponseBodypublic String test06() {rabbitTemplate.convertAndSend("fanoutExchange","","Hello,fanoutExchange:Queue!");return "💕6";}}

总结:

问题:为啥要使用RabbitMQ中交换机???

  1. 消息路由:交换机用于将消息从生产者发送到消费者之间建立起路由规则。它可以根据不同的路由键(routing key)将消息传递给不同的队列或者其他交换机,实现灵活的消息传递方式。

  2. 解耦和扩展性:通过使用交换机,生产者和消费者之间可以解耦。生产者只需要将消息发送到交换机上,并不需要关心具体的消费者。消费者可以根据自己的需求,绑定到交换机上接收特定类型的消息,这样可以实现系统的灵活扩展和升级。

  3. 发布-订阅模式:交换机支持发布-订阅模式,可以将消息广播给多个消费者。当多个消费者同时绑定到同一个交换机上时,交换机会将消息复制并传递给所有绑定的队列,实现消息的多播。

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

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

相关文章

8.Gateway服务网关

3.Gateway服务网关 Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等响应式编程和事件流技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式…

JVM工作原理与实战(二十五):堆的垃圾回收-垃圾回收算法

专栏导航 JVM工作原理与实战 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、垃圾回收算法介绍 1.垃圾回收算法的历史和分类 2.垃圾回收算法的评价标准 二、垃圾回收算法详解 1.标记清除算法 2.复制算法 3.标记整理算法 4.分代垃圾回收算法 总结 前言…

密码学的100个基本概念

密码学作为信息安全的基础,极为重要,本文分为上下两部分,总计10个章节,回顾了密码学的100个基本概念,供小伙伴们学习参考。本文将先介绍前五个章节的内容。 一、密码学历史 二、密码学基础 三、分组密码 四、序列密码 五、哈希…

生命在于折腾——WeChat机器人的研究和探索

一、前言 2022年,我玩过原神,当时看到了云崽的QQ机器人,很是感兴趣,支持各种插件,查询游戏内角色相关信息,当时我也自己写了几个插件,也看到很多大佬编写的好玩的插件,后来因为QQ不…

数据结构:搜索二叉树 | 红黑树 | 验证是否为红黑树

文章目录 1.红黑树的概述2.红黑树的性质3.红黑树的代码实现3.1.红黑树的节点定义3.2.红黑树的插入操作3.3.红黑树是否平衡 黑红树是一颗特殊的搜索二叉树,本文在前文的基础上,图解红黑树插入:前文 链接,完整对部分关键代码展示&a…

SG-8506CA 可编程晶体振荡器 (SPXO)

输出: LV-PECL频率范围: 50MHz ~ 800MHz电源电压: 2.5V to 3.3V外部尺寸规格: 7.0 5.0 1.5mm (8引脚)特性:用户指定一个起始频率, 7-bit I2C 地址:用户可编程: I2C 接口:基频的高频晶体:低抖动PLL技术应用:OTN, BTS, 测试设备 规格(特征) *1 这包括初…

Intel Atom + Artix-7 100T FPGA,CompactRIO单板控制器

模拟和数字I/O,RMC,DisplayPort,1.33 GHz双核CPU,1 GB DRAM,4 GB存储容量,Artix-7 100T FPGA,CompactRIO单板控制器 CompactRIO控制器是搭载了实时处理器和用户可编程FPGA的嵌入式控制器。其产…

Elasticsearch:聊天机器人、人工智能和人力资源:电信公司和企业组织的成功组合

作者:来自 Elastic Jrgen Obermann, Piotr Kobziakowski 让我们来谈谈大型企业人力资源领域中一些很酷且改变游戏规则的东西:生成式 AI 和 Elastic Stack 的绝佳组合。 现在,想象一下大型电信公司的典型人力资源部门 — 他们正在处理一百万件…

【Java IO】设计模式 (装饰者模式)

Java I/O 使用了装饰者模式来实现。 装饰者模式 请参考装饰者模式详解 装饰者(Decorator)和具体组件(ConcreteComponent)都继承自组件(Component),具体组件的方法实现不需要依赖于其它对象,而装饰者组合了一个组件,这样它可以装饰其它装饰者…

022-安全开发-PHP应用留言板功能超全局变量数据库操作第三方插件引用

022-安全开发-PHP应用&留言板功能&超全局变量&数据库操作&第三方插件引用 #知识点: 1、PHP留言板前后端功能实现 2、数据库创建&架构&增删改查 3、内置超全局变量&HTML&JS混编 4、第三方应用插件&传参&对象调用 演示案例&a…

cad二次开发autolisp(二)

目录 一、选择集1.1 选择集的创建1.2 选择集的编辑1.3 操作选择集 二、命令行设置对话框2.1 设置图层2.2 加载线型2.3 设置字体样式2.4 设置标注样式(了解即可) 三、符号表3.1 简介3.2 符号表查找3.2 符号表删改增 一、选择集 定义:批量选择…

苹果眼镜(Vision Pro)的开发者指南(5)-主要工具

主要工具有:Xcode、Reality Composer Pro、Unity 第一部分:【用Xcode进行开发】 开始使用Xcode为visionOS进行开发。将向你展示如何在你现有的项目中添加一个visionOS目标,或者构建一个全新的应用,在Xcode预览中创建原型,以及从Reality Composer Pro中导入内容。还将分享…

ComfyUI 基础教程(十一):秋葉aaaki 整合包 一键启动

秋葉aaaki大佬的ComfyUI整合包,解压即用,一键启动,预置不少插件(工作流节点)。 1.使用方法 🌟链接:https://pan.quark.cn/s/ff5b759671d7 下载网盘文件(ComfyUI-aki-v1.1),解压缩即可。(秋葉文件包里面的controlnet和模型文件太大了,我删除了) 点击A绘世启动器.e…

elementui 表单 resetFields 方法不生效问题解决

问题 调用 elementui 官方提供的表单重置方法 resetFields 方法重置表单不生效,相信很多小伙伴都遇到过这个问题。 解决方法 检查代码看每个表单项的 prop 与 v-model 绑定的属性值命名是否相同,不相同的话就会导致 resetFields 方法不生效的问题&am…

详细分析Java中的list.foreach()和list.stream().foreach()

目录 前言1. 基本知识2. 差异之处2.1 执行顺序2.2 串行并行2.3 复杂数据处理2.4 CRUD集合2.5 迭代器 3. 总结4. 彩蛋 前言 典故来源于项目中使用了两种方式的foreach,后面尝试体验下有何区别! 先看代码示例: 使用List的forEach&#xff1a…

Tomcat 简介安装

目录 1、概念介绍 Tomcat 组件 HTTP 请求过程 Tomcat 目录结构 Tomcat 命令 配置文件说明 2、安装环境 安装JDK 安装Tomcat 创建管理用户 3、搭建虚拟主机 1、概念介绍 端口:8080 Tomcat 服务器是一个免费的开放源代码的 Web 应用服务器, 按照 Sun 提供…

全双工通信协议:WebSocket

全双工通信协议:WebSockets 前言何时使用WebSocketsWebSocket APITextWebSocketHandlerWebSocketConfigurerWebSocket握手配置服务器允许的来源心跳包Java WebSocket API案例一:前端发送消息并接收后端响应案例二:模拟后端向前端推送消息案例…

Shell 虚拟机基线配置脚本示例

这是一个配置虚拟机基线的示例,包含关闭防火墙、禁用SElinux、设置时区、安装基础软件等。 这只是一个简单的模板,基线配置方面有很多,后续可以按照这个模板去逐步添加 代码示例 [rootbogon ~]# cat bastic.sh #!/bin/bashRED\E[1;31m GRE…

【C++】C++入门(一)

个人主页 : zxctsclrjjjcph 文章封面来自:艺术家–贤海林 如有转载请先通知 文章目录 1. 前言2. C关键字3. 命名空间3.1 命名空间定义3.2 命名空间的使用 4. C输入&输出 1. 前言 C是在C的基础之上,容纳进去了面向对象编程思想&#xff0…

【产品交互】超全面B端设计规范总结

不知不觉已经深耕在B端这个领域3年有余,很多人接触过B端后会觉得乏味,因为B端的设计在视觉上并没有C端那么有冲击力,更多的是结合业务逻辑,设计出符合业务需求的交互,以及界面排版的合理性,达到产品的可用性…