微服务框架SpringcloudAlibaba+Nacos集成RabbitMQ

目前公司使用jeepluscloud版本,这个版本没有集成消息队列,这里记录一下,集成的过程;这个框架跟ruoyi的那个微服务版本结构一模一样,所以也可以快速上手。

1.项目结构图:

配置类的东西做成一个公共的模块

在这里插入图片描述

rabbitmq模块:

在这里插入图片描述

2.核心配置

1.pom类

<?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.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><artifactId>jeeplus-common</artifactId><groupId>org.jeeplus</groupId><version>${revision}</version></parent><modelVersion>4.0.0</modelVersion><artifactId>jeeplus-common-rabbitmq</artifactId><packaging>jar</packaging><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency><dependency><groupId>org.jeeplus</groupId><artifactId>jeeplus-common-core</artifactId><version>${project.parent.version}</version></dependency></dependencies>
</project>

2.ConditionalOnRabbit

package com.jeeplus.common.rabbit.conditional;import org.springframework.context.annotation.Conditional;import java.lang.annotation.*;/*** 判断系统是否在启用了Rabbit, 未启用的情况下不将Bean注册到系统中** 使用场景: 在不使用Rabbit中间件但未去除Rabbit依赖的情况下, 通过配置文件中关闭Rabbit选项,* 同时将这个注解到有`@RabbitListener`标志的类上,让这个对象不注册到Spring容器中,* 从而避免`RabbitMQ`进行无限尝试重连服务器,导致项目一直抛出异常,影响开发和使用。** @author xxm* @since 2022/12/12*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnRabbitEnable.class)
public @interface ConditionalOnRabbit {}

3.OnRabbitEnable

package com.jeeplus.common.rabbit.conditional;import com.jeeplus.common.rabbit.configuration.RabbitMqProperties;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;/*** 判断是否在启用了Rabbit, 用来控制在没启用Rabbit情况下. 不将 @RabbitListener 修饰的监听器注册为Bean, 不然会导致无限尝试重连** @author xxm* @since 2022/12/12*/
public class OnRabbitEnable implements Condition {private final String rabbitPropertiesPrefix = "com.jeeplus.common.rabbit";/*** @param context* @param metadata* @return*/@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {RabbitMqProperties rabbitMqProperties = Binder.get(context.getEnvironment()).bind(rabbitPropertiesPrefix, RabbitMqProperties.class).orElse(new RabbitMqProperties());return rabbitMqProperties.isEnable();}}

4.BootxRabbitListenerConfigurer

package com.jeeplus.common.rabbit.configuration;import lombok.RequiredArgsConstructor;
import org.springframework.amqp.rabbit.annotation.RabbitListenerConfigurer;
import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistrar;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;/*** Rabbit 侦听器配置器** @author xxm* @since 2021/6/25*/
@Configuration
@RequiredArgsConstructor
public class BootxRabbitListenerConfigurer implements RabbitListenerConfigurer {private final DefaultMessageHandlerMethodFactory jsonHandlerMethodFactory;@Overridepublic void configureRabbitListeners(RabbitListenerEndpointRegistrar registrar) {registrar.setMessageHandlerMethodFactory(jsonHandlerMethodFactory);}}

5.BootxRabbitListenerConfigurer

package com.jeeplus.common.rabbit.configuration;import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;/*** 消息队列配置** @author xxm* @since 2021/6/25*/
@EnableRabbit
@Configuration
public class RabbitMqConfigurer {/*** 注册 RabbitTemplate 对象, 使用默认序列化方式*/@Beanpublic RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory, ObjectMapper objectMapper) {RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);// 使用系统同版jackson 序列化配置rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter(objectMapper));return rabbitTemplate;}/*** 添加默认消息序列化方式, 使用默认序列化方式*/@Beanpublic DefaultMessageHandlerMethodFactory jsonHandlerMethodFactory(ObjectMapper objectMapper) {DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();// 这里的转换器设置实现了 通过 @Payload 注解 自动反序列化message bodyMappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();converter.setObjectMapper(objectMapper);factory.setMessageConverter(converter);return factory;}}

6.RabbitMqConfigurer

package com.jeeplus.common.rabbit.configuration;import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;/*** 消息队列配置** @author xxm* @since 2021/6/25*/
@EnableRabbit
@Configuration
public class RabbitMqConfigurer {/*** 注册 RabbitTemplate 对象, 使用默认序列化方式*/@Beanpublic RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory, ObjectMapper objectMapper) {RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);// 使用系统同版jackson 序列化配置rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter(objectMapper));return rabbitTemplate;}/*** 添加默认消息序列化方式, 使用默认序列化方式*/@Beanpublic DefaultMessageHandlerMethodFactory jsonHandlerMethodFactory(ObjectMapper objectMapper) {DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();// 这里的转换器设置实现了 通过 @Payload 注解 自动反序列化message bodyMappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();converter.setObjectMapper(objectMapper);factory.setMessageConverter(converter);return factory;}}

7.RabbitMqProperties

package com.jeeplus.common.rabbit.configuration;import com.jeeplus.common.rabbit.conditional.ConditionalOnRabbit;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;/*** MQTT配置** @author xxm* @since 2022/12/12*/
@Getter
@Setter
@ConfigurationProperties("com.jeeplus.common.rabbit")
public class RabbitMqProperties {/*** 是否开启 RabbitMQ功能,* @see ConditionalOnRabbit 配合此注解使用*/private boolean enable = false;}

8.RabbitMqCommonAutoConfiguration

package com.jeeplus.common.rabbit;import org.springframework.boot.autoconfigure.SpringBootApplication;/*** RabbitMQ配置** @author xxm* @since 2022/5/3*/
@SpringBootApplication
public class RabbitMqCommonAutoConfiguration {}

在这里插入图片描述

9.org.springframework.boot.autoconfigure.AutoConfiguration.imports

RabbitMqCommonAutoConfiguration

10.spring.factories

## 配置自定义 starter 的自动化配置
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.jeeplus.common.rabbit.RabbitMqCommonAutoConfiguration

3. nacos配置

哪一个服务模块需要消息队列,就在对应的yml文件中配置 rabbit链接
在这里插入图片描述

  #rabbitmqrabbitmq:host: localhostport: 5627username: rootpassword: root123virtual-host: /publisher-confirm-type: correlatedlistener:simple:acknowledge-mode: manual

4.服务中调用rabbitmq

建立两个包,配置类和监听类

在这里插入图片描述

1.mq模板配置

package com.jeeplus.duxin.config;import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;/*** mq模板* @author lgn* @date 2023/10/28 10:15*/
@Configuration
public class MyRabbitConfig {private RabbitTemplate rabbitTemplate;@Primary@Beanpublic RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);this.rabbitTemplate = rabbitTemplate;rabbitTemplate.setMessageConverter(messageConverter());initRabbitTemplate();return rabbitTemplate;}@Beanpublic MessageConverter messageConverter() {return new Jackson2JsonMessageConverter();}/*** 定制RabbitTemplate* 1、服务收到消息就会回调*      1、spring.rabbitmq.publisher-confirms: true*      2、设置确认回调* 2、消息正确抵达队列就会进行回调*      1、spring.rabbitmq.publisher-returns: true*         spring.rabbitmq.template.mandatory: true*      2、设置确认回调ReturnCallback** 3、消费端确认(保证每个消息都被正确消费,此时才可以broker删除这个消息)**/// @PostConstruct  //MyRabbitConfig对象创建完成以后,执行这个方法public void initRabbitTemplate() {/*** 1、只要消息抵达Broker就ack=true* correlationData:当前消息的唯一关联数据(这个是消息的唯一id)* ack:消息是否成功收到* cause:失败的原因*///设置确认回调rabbitTemplate.setConfirmCallback((correlationData,ack,cause) -> {System.out.println("confirm...correlationData["+correlationData+"]==>ack:["+ack+"]==>cause:["+cause+"]");});/*** 只要消息没有投递给指定的队列,就触发这个失败回调* message:投递失败的消息详细信息* replyCode:回复的状态码* replyText:回复的文本内容* exchange:当时这个消息发给哪个交换机* routingKey:当时这个消息用哪个路邮键*/rabbitTemplate.setReturnCallback((message,replyCode,replyText,exchange,routingKey) -> {System.out.println("Fail Message["+message+"]==>replyCode["+replyCode+"]" +"==>replyText["+replyText+"]==>exchange["+exchange+"]==>routingKey["+routingKey+"]");});}
}

2.服务交换机 队列设置

初始化交换机,队列,建立绑定。

package com.jeeplus.duxin.config;import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.Exchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.HashMap;/*** 服务交换机 队列设置* @author lgn* @date 2023/10/28 10:16*/
@Configuration
public class MyRabbitMQConfig {/* 容器中的Queue、Exchange、Binding 会自动创建(在RabbitMQ)不存在的情况下 *//*    *//*** 初始化队列* 死信队列** @return*//*@Beanpublic Queue orderDelayQueue() {*//*Queue(String name,  队列名字boolean durable,  是否持久化boolean exclusive,  是否排他boolean autoDelete, 是否自动删除Map<String, Object> arguments) 属性*//*HashMap<String, Object> arguments = new HashMap<>();arguments.put("x-dead-letter-exchange", "order-event-exchange");arguments.put("x-dead-letter-routing-key", "order.release.order");arguments.put("x-message-ttl", 60000); // 消息过期时间 1分钟Queue queue = new Queue("order.delay.queue", true, false, false, arguments);return queue;}*//*    *//*** 初始化队列* 普通队列** @return*//*@Beanpublic Queue orderReleaseQueue() {Queue queue = new Queue("order.release.order.queue", true, false, false);return queue;}*//*    *//**** TopicExchange* 创建topic类型的交换机* @return*//*@Beanpublic Exchange orderEventExchange() {*//**   String name,*   boolean durable,*   boolean autoDelete,*   Map<String, Object> arguments* *//*return new TopicExchange("order-event-exchange", true, false);}*//*    *//*** 路由和交换机进行绑定 设置路由key* @author lgn* @date 2023/10/28 10:33* @return Binding*//*@Beanpublic Binding orderCreateBinding() {*//** String destination, 目的地(队列名或者交换机名字)* DestinationType destinationType, 目的地类型(Queue、Exhcange)* String exchange,* String routingKey,* Map<String, Object> arguments* *//*return new Binding("order.delay.queue",Binding.DestinationType.QUEUE,"order-event-exchange","order.create.order",null);}*//*    @Beanpublic Binding orderReleaseBinding() {return new Binding("order.release.order.queue",Binding.DestinationType.QUEUE,"order-event-exchange","order.release.order",null);}*//*** 订单释放直接和库存释放进行绑定* @return*//*@Beanpublic Binding orderReleaseOtherBinding() {return new Binding("stock.release.stock.queue",Binding.DestinationType.QUEUE,"order-event-exchange","order.release.other.#",null);}*//*    *//*** 初始化队列* 商品秒杀队列* @return*//*@Beanpublic Queue orderSecKillOrrderQueue() {Queue queue = new Queue("order.seckill.order.queue", true, false, false);return queue;}@Beanpublic Binding orderSecKillOrrderQueueBinding() {//String destination, DestinationType destinationType, String exchange, String routingKey,// 			Map<String, Object> argumentsBinding binding = new Binding("order.seckill.order.queue",Binding.DestinationType.QUEUE,"order-event-exchange","order.seckill.order",null);return binding;}*//*** BOM模块的交换机* TopicExchange* 创建topic类型的交换机* @return*/@Beanpublic Exchange orderEventExchange() {/**   String name,*   boolean durable,*   boolean autoDelete,*   Map<String, Object> arguments* */return new TopicExchange("bom-event-exchange", true, false);}/*** 初始化BOM队列* @return*/@Beanpublic Queue bomMaintenanceQueue() {Queue queue = new Queue("bom.maintenance.queue", true, false, false);return queue;}/*** bom* 路由和交换机进行绑定 设置路由key* @author lgn* @date 2023/10/28 10:33* @return Binding*/@Beanpublic Binding bomCreateBinding() {/** String destination, 目的地(队列名或者交换机名字)* DestinationType destinationType, 目的地类型(Queue、Exhcange)* String exchange,* String routingKey,* Map<String, Object> arguments* */return new Binding("bom.maintenance.queue",Binding.DestinationType.QUEUE,"bom-event-exchange","bom.maintenance.create",null);}/*** 初始化产品存货档案队列* @return*/@Beanpublic Queue stockDocQueue() {Queue queue = new Queue("stock.doc.queue", true, false, false);return queue;}/*** 存货档案StockDoc* 路由和交换机进行绑定 设置路由key* @author lgn* @date 2023/10/28 10:33* @return Binding*/@Beanpublic Binding docCreateBinding() {/** String destination, 目的地(队列名或者交换机名字)* DestinationType destinationType, 目的地类型(Queue、Exhcange)* String exchange,* String routingKey,* Map<String, Object> arguments* */return new Binding("stock.doc.queue",Binding.DestinationType.QUEUE,"bom-event-exchange","stock.doc.create",null);}/*** 调用C++模块的交换机* TopicExchange* 创建topic类型的交换机* @return*/@Beanpublic Exchange cEventExchange() {/**   String name,*   boolean durable,*   boolean autoDelete,*   Map<String, Object> arguments* */return new TopicExchange("c-event-exchange", true, false);}/*** 初始化c++生成记录文件队列* @return*/@Beanpublic Queue cCreatFileQueue() {Queue queue = new Queue("c.creatfile.queue", true, false, false);return queue;}/*** 初始化c++签名队列* @return*/@Beanpublic Queue cDealQueue() {Queue queue = new Queue("c.deal.queue", true, false, false);return queue;}/** * 创建绑定关系* @author lgn* @date 2023/10/30 9:34* @return Binding*/@Beanpublic Binding cCreatFileCreateBinding() {/** String destination, 目的地(队列名或者交换机名字)* DestinationType destinationType, 目的地类型(Queue、Exhcange)* String exchange,* String routingKey,* Map<String, Object> arguments* */return new Binding("c.creatfile.queue",Binding.DestinationType.QUEUE,"c-event-exchange","c.creatFile.create",null);}/*** 创建绑定关系* @author lgn* @date 2023/10/30 9:34* @return Binding*/@Beanpublic Binding cDealBinding() {/** String destination, 目的地(队列名或者交换机名字)* DestinationType destinationType, 目的地类型(Queue、Exhcange)* String exchange,* String routingKey,* Map<String, Object> arguments* */return new Binding("c.deal.queue",Binding.DestinationType.QUEUE,"c-event-exchange","c.deal.create",null);}}

3.监听队列 接收消息

消费方消费消息

package com.jeeplus.duxin.listener;import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;import java.io.IOException;/*** 监听路由信息* @author lgn* @date 2023/10/28 10:33*/
@Slf4j
@Component
//@RabbitListener标注在方法上,直接监听指定的队列,此时接收的参数需要与发送时类型一致
//@RabbitListener 注解是指定某方法作为消息消费的方法,例如监听某 Queue 里面的消息。
@RabbitListener(queues = "bom.maintenance.queue")
public class MQTestListener {//@RabbitListener 可以标注在类上面,需配合 @RabbitHandler 注解一起使用//@RabbitListener 标注在类上面表示当有收到消息的时候,就交给 @RabbitHandler 的方法处理,根据接受的参数类型进入具体的方法中。@RabbitHandlerpublic void listener(String info,Channel channel, Message message) throws IOException {System.out.println("=============接收消息开始执行:"+info);try {channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);} catch (Exception e) {channel.basicReject(message.getMessageProperties().getDeliveryTag(),true);}}
}

5.使用

使用起来也非常方便:
在业务service中直接调用,生产者消息发送。

	/*** mqTest* @author lgn* @date 2023/10/28 10:03* @return Object*/public String mqTest() {//TODO 订单创建成功,发送消息给MQrabbitTemplate.convertAndSend("bom-event-exchange","bom.maintenance.create","1234");return null;}

希望对你有用!

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

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

相关文章

Spring- SpringBean生命周期源码解析

附带资料JFR介绍&#xff1a;深度探索JFR - JFR详细介绍与生产问题定位落地 - 1. JFR说明与启动配置 - 知乎 Spring最重要的功能就是帮助程序员创建对象&#xff08;也就是IOC&#xff09;&#xff0c;而启动Spring就是为创建Bean对象做准备&#xff0c;所以我们先明白Spring到…

点云从入门到精通技术详解100篇-基于三维点云的路况语义分割

目录 前言 国内外研究现状 基于传统方法的点云语义分割 基于深度学习方法的点云语义分割

医疗数据可视化大屏:重构医疗决策的未来

医疗行业一直是信息密集型领域之一&#xff0c;它的复杂性不仅在于患者病历和医疗数据的海量积累&#xff0c;还包括了病情诊断、医疗资源分配、病患治疗等多层次的挑战。随着信息技术的不断发展&#xff0c;医疗数据可视化大屏成为了一种创新性的工具&#xff0c;它为医疗管理…

TypeScript深度剖析:TypeScript 中枚举类型应用场景?

文章目录 一、是什么二、使用数字枚举字符串枚举异构枚举本质 三、应用场景 一、是什么 枚举是一个被命名的整型常数的集合&#xff0c;用于声明一组命名的常数,当一个变量有几种可能的取值时,可以将它定义为枚举类型 通俗来说&#xff0c;枚举就是一个对象的所有可能取值的集…

阿里云推出AI编程工具“通义灵码“;生成式 AI 入门教程 2

&#x1f989; AI新闻 &#x1f680; 阿里云推出AI编程工具"通义灵码"&#xff0c;支持多种语言及实时续写功能 摘要&#xff1a;阿里云推出了一款名为"通义灵码"的AI编程工具&#xff0c;支持多种主流编程语言&#xff0c;包括Java、Python、Go等。该工…

java spring boot 注解、接口和问题解决方法(持续更新)

注解 RestController 是SpringMVC框架中的一个注解&#xff0c;它结合了Controller和ResponseBody两个注解的功能&#xff0c;用于标记一个类或者方法&#xff0c;表示该类或方法用于处理HTTP请求&#xff0c;并将响应的结果直接返回给客户端&#xff0c;而不需要进行视图渲染…

IDEA 设置代码注释模板

功能简介&#xff1a; 每次看别人代码时&#xff0c;面对毫无注释的类&#xff0c;除了头大还是头大&#xff0c; 以下提供了一种代码类注释模板 新建java类的时候&#xff0c;自动增加类注释&#xff0c;养成代码开发好习惯 效果展示&#xff1a; 代码模板&#xff1a; #if (…

css——半圆实心

案例 代码 <view class"circleBox"></view>.circleBox {width: 50px;height: 100px;background: red;border-radius: 100px 0 0 100px; }

ubuntu20.04 conda pack 打包虚拟环境,直接将其用到其他终端

在本机ubuntu20.04下配置的虚拟环境&#xff0c;想到将其整个放到新建的docker(ubuntu20.04)下使用&#xff0c;操作步骤如下&#xff1a; # 一、在ubuntu1下打包虚拟环境 # 安装conda-pack pip install conda-pack# 进入需要打包的虚拟环境,这里将目标虚拟环境名称为goal_env…

添加环境变量

echo export PYENV_ROOT"$HOME/.pyenv" >> ~/.bash_profile echo export PATH"$PYENV_ROOT/bin:$PATH" >> ~/.bash_profilepipenv --python 3.6 #指定使用Python3.6的虚拟环境 pipenv --two #使用系统的Python2在创建虚拟环境 pipenv --three …

单点登录。

Java单点登录&#xff08;SSO&#xff09;是一种在多个应用程序和系统之间共享用户身份验证信息的技术。它允许用户只需一次登录即可访问多个应用程序和系统&#xff0c;而不必每次都输入用户名和密码。Java SSO实现的基本思路是&#xff0c;当用户访问第一个应用程序时&#x…

Flutter GetX的使用

比较强大的状态管理框架 引入库&#xff1a; dependencies:get: ^4.6.6一.实现一个简单的demo 实现一个计数器功能 代码如下&#xff1a; import package:flutter/material.dart; import package:get/get.dart;void main() > runApp(const GetMaterialApp(home: Home()…

Linux: MV指令(覆盖替换重命名)

MV指令 mv [-bfiuv] [–help] [–version] [-S <附加字尾>] [-V <方法>] [源文件或目录] [目标文件或目录]-b 若需覆盖文件&#xff0c;则覆盖前先行备份-f 若目标文件或目录与现有的文件或目录重复&#xff0c;则直接覆盖现有的文件或目录-i 覆盖前先行询问用户–…

代码随想录训练营第57天 | 647. 回文子串 ● 516.最长回文子序列

647. 回文子串 题目链接&#xff1a;https://leetcode.com/problems/palindromic-substrings 解法&#xff1a; 这道题代码量不大&#xff0c;但是要每一步都需要认真考虑。 1. 定义dp[i][j]的含义 dp[i][j]&#xff1a;表示区间范围[i,j] &#xff08;注意是左闭右闭&a…

组件与Props:React中构建可复用UI的基石

目录 组件&#xff1a;构建现代UI的基本单位 Props&#xff1a;组件之间的数据传递 Props的灵活性&#xff1a;构建可配置的组件 组件间的通信&#xff1a;通过回调函数传递数据 总结&#xff1a; 组件&#xff1a;构建现代UI的基本单位 组件是前端开发中的关键概念之一。…

电脑如何录制小视频

如果你想在你的电脑上录制视频分享给你的朋友或者亲人&#xff0c;无论你的电脑是win还是mac&#xff0c;都可以在本篇文章中找到电脑录制视频的详细教程。小编为你们整理了2种不同系统电脑的录制详细流程&#xff0c;继续阅读查看吧&#xff01; 第一部分&#xff1a;windows…

中国等28个国家发布《布莱切利宣言》,鼓励AI以安全方式发展

英国时间11月1日&#xff0c;中国、美国、英国、法国、德国等28个国家和欧盟&#xff0c;在英国的布莱切利庄园签署了&#xff0c;首个全球性人工智能&#xff08;AI&#xff09;声明——《布莱切利宣言》。 该宣言明确指出了AI对人类社会的巨大机遇&#xff0c;但AI需要以人为…

http和https的区别,以及https涉及到的加密过程

一.http与https的介绍 http:超文本传输协议&#xff0c;是互联网应用最广泛的一种网络协议。设计的最初目的是为了提供一种发布和接收HTML页面的方法。是以明文的形式来传输的&#xff0c;所以就会存在一定的安全隐患&#xff08;因为攻击者可以截取web服务器和网站相关的报文…

【C语法学习】16 - fclose()函数

文章目录 1 函数原型2 参数3 返回值4 示例 1 函数原型 fclose()&#xff1a;关闭已打开的文件&#xff0c;并刷新缓冲区&#xff0c;函数原型如下&#xff1a; int fclose(FILE *stream);2 参数 fclose()函数只有一个参数stream&#xff1a; 参数stream是一个指向FILE类型结…

BIOS开发笔记 - CMOS

CMOS原来指的是一种生产电子电路的工艺,在PC上一般指的是RTC电路单元,因为早期它是由这种工艺生产出来的,所以又把RTC称作了CMOS。 RTC(Real Time Clock)即实时时钟,用于保存记录时间和日期,也可以用来做定时开机功能。RTC靠一组独立的电源给它供电,这样设计的目的就是…