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

RabbitMQ 发布订阅模式,routing路由模式,topic模式

发布订阅模式

一个消息可以由多个消费者消费同一个消息

 消费者1和2同时消费了该消息

举例

public static void main(String[] args) throws IOException, TimeoutException {//1 创建连接工厂ConnectionFactory connectionFactory=new ConnectionFactory();//2 设置rabbitmq  ip地址connectionFactory.setHost("localhost");//3 创建连接对象   Conection对象Connection connection=connectionFactory.newConnection();//4 创建管道  ChanelChannel channel=connection.createChannel();//5 设置队列属性/*** 第一个参数:队列的名称* 第二个参数:队列是否要持久化* 第三个参数:是否排他性(是否在同一个Connection,如果设置为true,不同的Connection是获得不到消息的)* 第四个参数:是否自动删除消息* 第五个参数:是否要设置一些额外的参数*///channel.queueDeclare("02-work",false,false,true,null);/*** 发布订阅模式需要指定交换机和类型,不能用上面的模式* 交换机 Exchange 只负责转发消息,不具备存储消息的能力,因此如果没有任何队列与Exchange绑定* 或者没有符合路由规则的队列,那么消息会丢失* 第一个参数:交换机名字* 第二个参数:交换机类型*  fanout:广播,将消息交给所有绑定到交换机的队列*  direct:定向,把消息交给符合指定routing key的队列*  topic:通配符,把消息交给符合routing pattern(路由模式)的队列*/channel.exchangeDeclare("03-pubsub1", "fanout");//6 发送消息/*** 第一个参数:交换机名称 没有交换机就设置""* 第二个参数:路由key* 第三个参数:消息属性* 第四个参数:消息内容*/channel.basicPublish("03-pubsub1","", MessageProperties.PERSISTENT_TEXT_PLAIN, "hello rabbitMQ".getBytes());//7 关闭消息//channel.close();connection.close();
}

 消费者1和2同时消费了该消息,比如说消息是发短信,发邮件,  那么1和发短息  2可以发邮件

public static void main(String[] args) throws IOException, TimeoutException {//1 创建连接工厂ConnectionFactory connectionFactory=new ConnectionFactory();//2 设置rabbitmq  ip地址connectionFactory.setHost("localhost");//3 创建连接对象   Conection对象Connection connection=connectionFactory.newConnection();//4 创建管道  ChanelChannel channel=connection.createChannel();//5 设置队列属性/*** 第一个参数:队列的名称* 第二个参数:队列是否要持久化* 第三个参数:是否排他性(是否在同一个Connection,如果设置为true,不同的Connection是获得不到消息的)* 第四个参数:是否自动删除消息* 第五个参数:是否要设置一些额外的参数*///channel.queueDeclare("02-work",false,false,true,null);//channel.basicQos(1);//6 使用chanel 去 rabbitmq 获取消息进行消费/*** 第一个参数:队列的名称* 第二个参数:是否自动签收* 第三个参数:消息属性* 第四个参数:消息内容*/channel.exchangeDeclare("03-pubsub1", "fanout");//绑定String queue = channel.queueDeclare().getQueue();channel.queueBind(queue, "03-pubsub1", "");channel.basicConsume(queue, false,new DeliverCallback(){/*** 当消息从mq 中取出来了会回调这个方法* 消费者消费消息就在这个  handle中进行处理*/@Overridepublic void handle(String s, Delivery delivery){System.out.println("消费者 1  消息中的内容为:"+new String(delivery.getBody()));}},new CancelCallback(){/*** 当消息取消了会回调这个方法*/@Overridepublic void handle(String s) throws IOException {System.out.println(111);}});//7 关闭消息   注意消费者 需要持续监听,不要关闭//channel.close();//connection.close();
}

routing路由模式

就是说哪些让谁干

哪些让谁干区分出来

也可以让所有消费者都消费

选择性的让某个消费者消费,或者都消费

 生产者

public static void main(String[] args) throws IOException, TimeoutException {//1 创建连接工厂ConnectionFactory connectionFactory=new ConnectionFactory();//2 设置rabbitmq  ip地址connectionFactory.setHost("localhost");//3 创建连接对象   Conection对象Connection connection=connectionFactory.newConnection();//4 创建管道  ChanelChannel channel=connection.createChannel();//5 设置队列属性/*** 第一个参数:队列的名称* 第二个参数:队列是否要持久化* 第三个参数:是否排他性(是否在同一个Connection,如果设置为true,不同的Connection是获得不到消息的)* 第四个参数:是否自动删除消息* 第五个参数:是否要设置一些额外的参数*///channel.queueDeclare("02-work",false,false,true,null);/*** 发布订阅模式需要指定交换机和类型,不能用上面的模式* 交换机 Exchange 只负责转发消息,不具备存储消息的能力,因此如果没有任何队列与Exchange绑定* 或者没有符合路由规则的队列,那么消息会丢失* 第一个参数:交换机名字* 第二个参数:交换机类型*  fanout:广播,将消息交给所有绑定到交换机的队列*  direct:定向,把消息交给符合指定routing key的队列*  topic:通配符,把消息交给符合routing pattern(路由模式)的队列*/channel.exchangeDeclare("04-routing1", "direct");//6 发送消息/*** 第一个参数:交换机名称 没有交换机就设置""* 第二个参数:路由key  routing模式需要路由key* 第三个参数:消息属性* 第四个参数:消息内容*/channel.basicPublish("04-routing1","info", MessageProperties.PERSISTENT_TEXT_PLAIN, "hello rabbitMQ".getBytes());//7 关闭消息//channel.close();connection.close();
}

 消费者1

public static void main(String[] args) throws IOException, TimeoutException {//1 创建连接工厂ConnectionFactory connectionFactory=new ConnectionFactory();//2 设置rabbitmq  ip地址connectionFactory.setHost("localhost");//3 创建连接对象   Conection对象Connection connection=connectionFactory.newConnection();//4 创建管道  ChanelChannel channel=connection.createChannel();//5 设置队列属性/*** 第一个参数:队列的名称* 第二个参数:队列是否要持久化* 第三个参数:是否排他性(是否在同一个Connection,如果设置为true,不同的Connection是获得不到消息的)* 第四个参数:是否自动删除消息* 第五个参数:是否要设置一些额外的参数*///channel.queueDeclare("02-work",false,false,true,null);//channel.basicQos(1);//6 使用chanel 去 rabbitmq 获取消息进行消费/*** 第一个参数:队列的名称* 第二个参数:是否自动签收* 第三个参数:消息属性* 第四个参数:消息内容*/channel.exchangeDeclare("04-routing1", "direct");//绑定String queue = channel.queueDeclare().getQueue();//可与绑定多个channel.queueBind(queue, "04-routing1", "info");channel.queueBind(queue, "04-routing1", "error");channel.queueBind(queue, "04-routing1", "waring");channel.basicConsume(queue, true,new DeliverCallback(){/*** 当消息从mq 中取出来了会回调这个方法* 消费者消费消息就在这个  handle中进行处理*/@Overridepublic void handle(String s, Delivery delivery){System.out.println("消费者 1  消息中的内容为:"+new String(delivery.getBody()));}},new CancelCallback(){/*** 当消息取消了会回调这个方法*/@Overridepublic void handle(String s) throws IOException {System.out.println(111);}});//7 关闭消息   注意消费者 需要持续监听,不要关闭//channel.close();//connection.close();
}

消费者2

public static void main(String[] args) throws IOException, TimeoutException {//1 创建连接工厂ConnectionFactory connectionFactory=new ConnectionFactory();//2 设置rabbitmq  ip地址connectionFactory.setHost("localhost");//3 创建连接对象   Conection对象Connection connection=connectionFactory.newConnection();//4 创建管道  ChanelChannel channel=connection.createChannel();//5 设置队列属性/*** 第一个参数:队列的名称* 第二个参数:队列是否要持久化* 第三个参数:是否排他性(是否在同一个Connection,如果设置为true,不同的Connection是获得不到消息的)* 第四个参数:是否自动删除消息* 第五个参数:是否要设置一些额外的参数*///channel.queueDeclare("02-work",false,false,true,null);//channel.basicQos(1);//6 使用chanel 去 rabbitmq 获取消息进行消费/*** 第一个参数:队列的名称* 第二个参数:是否自动签收* 第三个参数:消息属性* 第四个参数:消息内容*/channel.exchangeDeclare("04-routing1", "direct");//绑定String queue = channel.queueDeclare().getQueue();//可与绑定多个channel.queueBind(queue, "04-routing1", "trace");channel.basicConsume(queue, true,new DeliverCallback(){/*** 当消息从mq 中取出来了会回调这个方法* 消费者消费消息就在这个  handle中进行处理*/@Overridepublic void handle(String s, Delivery delivery){System.out.println("消费者 2  消息中的内容为:"+new String(delivery.getBody()));}},new CancelCallback(){/*** 当消息取消了会回调这个方法*/@Overridepublic void handle(String s) throws IOException {System.out.println(111);}});//7 关闭消息   注意消费者 需要持续监听,不要关闭//channel.close();//connection.close();
}

上面的只有消费者1消费了消息 

可以根据channel.queueBind(queue, "04-routing1", "trace"); 绑定消息  也可以让1和2都消费,

 

topic模式和Routing模式高度相识,用通配符的形式指定让谁消费,或者都消费

 生产者

public static void main(String[] args) throws IOException, TimeoutException {//1 创建连接工厂ConnectionFactory connectionFactory=new ConnectionFactory();//2 设置rabbitmq  ip地址connectionFactory.setHost("localhost");//3 创建连接对象   Conection对象Connection connection=connectionFactory.newConnection();//4 创建管道  ChanelChannel channel=connection.createChannel();//5 设置队列属性/*** 第一个参数:队列的名称* 第二个参数:队列是否要持久化* 第三个参数:是否排他性(是否在同一个Connection,如果设置为true,不同的Connection是获得不到消息的)* 第四个参数:是否自动删除消息* 第五个参数:是否要设置一些额外的参数*///channel.queueDeclare("02-work",false,false,true,null);/*** 发布订阅模式需要指定交换机和类型,不能用上面的模式* 交换机 Exchange 只负责转发消息,不具备存储消息的能力,因此如果没有任何队列与Exchange绑定* 或者没有符合路由规则的队列,那么消息会丢失* 第一个参数:交换机名字* 第二个参数:交换机类型*  fanout:广播,将消息交给所有绑定到交换机的队列*  direct:定向,把消息交给符合指定routing key的队列*  topic:通配符,把消息交给符合routing pattern(路由模式)的队列*/channel.exchangeDeclare("05-topic1", "topic");//6 发送消息/*** 第一个参数:交换机名称 没有交换机就设置""* 第二个参数:路由key  routing模式需要路由key* 第三个参数:消息属性* 第四个参数:消息内容*/channel.basicPublish("05-topic1","employee.save", MessageProperties.PERSISTENT_TEXT_PLAIN, "hello rabbitMQ".getBytes());//7 关闭消息//channel.close();connection.close();
}

消费者1

public static void main(String[] args) throws IOException, TimeoutException {//1 创建连接工厂ConnectionFactory connectionFactory=new ConnectionFactory();//2 设置rabbitmq  ip地址connectionFactory.setHost("localhost");//3 创建连接对象   Conection对象Connection connection=connectionFactory.newConnection();//4 创建管道  ChanelChannel channel=connection.createChannel();//5 设置队列属性/*** 第一个参数:队列的名称* 第二个参数:队列是否要持久化* 第三个参数:是否排他性(是否在同一个Connection,如果设置为true,不同的Connection是获得不到消息的)* 第四个参数:是否自动删除消息* 第五个参数:是否要设置一些额外的参数*///channel.queueDeclare("02-work",false,false,true,null);//channel.basicQos(1);//6 使用chanel 去 rabbitmq 获取消息进行消费/*** 第一个参数:队列的名称* 第二个参数:是否自动签收* 第三个参数:消息属性* 第四个参数:消息内容*/channel.exchangeDeclare("05-topic1", "topic");//绑定String queue = channel.queueDeclare().getQueue();//可与绑定多个channel.queueBind(queue, "05-topic1", "employee.*");channel.basicConsume(queue, true,new DeliverCallback(){/*** 当消息从mq 中取出来了会回调这个方法* 消费者消费消息就在这个  handle中进行处理*/@Overridepublic void handle(String s, Delivery delivery){System.out.println("消费者 1  消息中的内容为:"+new String(delivery.getBody()));}},new CancelCallback(){/*** 当消息取消了会回调这个方法*/@Overridepublic void handle(String s) throws IOException {System.out.println(111);}});//7 关闭消息   注意消费者 需要持续监听,不要关闭//channel.close();//connection.close();
}

消费者2

public static void main(String[] args) throws IOException, TimeoutException {//1 创建连接工厂ConnectionFactory connectionFactory=new ConnectionFactory();//2 设置rabbitmq  ip地址connectionFactory.setHost("localhost");//3 创建连接对象   Conection对象Connection connection=connectionFactory.newConnection();//4 创建管道  ChanelChannel channel=connection.createChannel();//5 设置队列属性/*** 第一个参数:队列的名称* 第二个参数:队列是否要持久化* 第三个参数:是否排他性(是否在同一个Connection,如果设置为true,不同的Connection是获得不到消息的)* 第四个参数:是否自动删除消息* 第五个参数:是否要设置一些额外的参数*///channel.queueDeclare("02-work",false,false,true,null);//channel.basicQos(1);//6 使用chanel 去 rabbitmq 获取消息进行消费/*** 第一个参数:队列的名称* 第二个参数:是否自动签收* 第三个参数:消息属性* 第四个参数:消息内容*/channel.exchangeDeclare("05-topic1", "topic");//绑定String queue = channel.queueDeclare().getQueue();//可与绑定多个channel.queueBind(queue, "05-topic1", "user.*");channel.basicConsume(queue, true,new DeliverCallback(){/*** 当消息从mq 中取出来了会回调这个方法* 消费者消费消息就在这个  handle中进行处理*/@Overridepublic void handle(String s, Delivery delivery){System.out.println("消费者 2  消息中的内容为:"+new String(delivery.getBody()));}},new CancelCallback(){/*** 当消息取消了会回调这个方法*/@Overridepublic void handle(String s) throws IOException {System.out.println(111);}});//7 关闭消息   注意消费者 需要持续监听,不要关闭//channel.close();//connection.close();
}

结果就是消费者1消费了消息

所有工作模式总结

 

相关文章:

RabbitMQ 发布订阅模式,routing路由模式,topic模式

发布订阅模式 一个消息可以由多个消费者消费同一个消息 消费者1和2同时消费了该消息 举例 public static void main(String[] args) throws IOException, TimeoutException {//1 创建连接工厂ConnectionFactory connectionFactorynew ConnectionFactory();//2 设置rabbitmq …...

又一款可视化神器,开源了!

在互联网数据大爆炸的这几年,各类数据处理、数据可视化的需求使得 GitHub 上诞生了一大批高质量的 BI 工具。 借助这些 BI 工具,我们能够大幅提升数据分析效率、生成更高质量的项目报告,让用户通过直观的数据看到结果,减低沟通成…...

干货 | 中科院心理所考研复试经验分享

Hello,大家好! 这里是壹脑云科研圈,我是喵君姐姐~ 此时此刻,23年考研的小伙伴估计正在为复试进行准备吧,大家都准备得怎么样了呢? 今天为大家带来的就是我国顶级心理学研究结构—中科院心理所…...

Redis基础知识概述

Redis基础知识概述 文章目录 Redis基础知识概述一、Redis简介二、NoSQL技术三、Redis的高并发和快速原因四、Redis为什么是单线程的 五、单线程的优劣势1、优势2、劣势 六、Redis高并发总结七、在java中使用Redis1、添加Jedis依赖 八、Redis在Java Web中的应用1、存储缓存用的数…...

开心档之C++ 引用

C 引用 引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。 C 引用 vs 指针 引用很容易与指针混淆,它们之间有三个主要的不同:…...

后台优化主要分为哪些?工作内容及流程是什么?

什么是5G网络优化? 顾名思义就是对4G/5G无线网络进行测试,分析,优化的专业技术工作。网络优化工作的进展程度,直接关系着我们对4G/5G无线网络的使用体验。 网络优化工程师通过对现已运行的手机通话网络进行话务数据分析、现场测…...

二叉树及其遍历

文章目录 二叉树树的定义二叉树的定义遍历先序遍历中序遍历后序遍历层次遍历定义队列层次创建二叉树层次遍历 二叉树 树是一种非线性的数据结构,由若干个节点组成,节点之间存在一种父子关系,具有层次结构。二叉树是一种特殊的树结构&#xff…...

java 版本企业电子招投标采购系统源码之登录页面

​ 信息数智化招采系统 服务框架:Spring Cloud、Spring Boot2、Mybatis、OAuth2、Security 前端架构:VUE、Uniapp、Layui、Bootstrap、H5、CSS3 涉及技术:Eureka、Config、Zuul、OAuth2、Security、OSS、Turbine、Zipkin、Feign、Monitor、…...

第五章 使用RAID与LVM磁盘阵列技术

第五章 使用RAID与LVM磁盘阵列技术 一、RAID磁盘冗余阵列 1、部署磁盘阵列 (1)、RAID0、1、5、10方案技术对比 RAID级别最少硬盘可用容量读写性能安全性特点02nn低追求最大容量和速度,任何一块盘损坏,数据全部异常。12n/2n高追…...

LeetCode 560. 和为 K 的子数组

LeetCode 560. 和为 K 的子数组 给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的连续子数组的个数 。 示例 1: 输入:nums [1,1,1], k 2 输出:2示例 2: 输入:nums [1,2,3], k 3 …...

后端要一次性返回我10万条数据

问题描述 面试官:后端一次性返回10万条数据给你,你如何处理?我:歪嘴一笑,what the f**k! 问题考察点 看似无厘头的问题,实际上考查候选人知识的广度和深度,虽然在工作中这种情况很少遇到... …...

汽车智能化「出海」红利

在高阶智能座舱中,车载导航产品作为与用户体验息息相关的模块之一,同样也进入了升级迭代周期。 基于高精度地图渲染、高精度定位算法、AR等技术的车道级导航、AR导航等产品快速上车,但同时随着人机交互多模发展以及3D沉浸式用户体验需求趋势下…...

Windows10资源管理器使用

文章目录 前言二、关联菜单操作1.分组展示2.添加选择复选框3.使用窗格模式4.功能区折叠二、“文件夹选项”对话框操作1.访问模式调整2.状态栏控制总结前言 目前Windows系统中的使用较多当属Windows10,资源管理器属于Windows系统中一个常用工具。本文总结了Windows 10 专业版下…...

【视频教程解读】Window上安装和使用autogluon V0.7

1.使用conda安装的python环境 教程使用的是极简版miniconda,由于我们的电脑中安装了anaconda,所以不需要进行进一步安装。python版本为3.9,博客里面有anaconda和python版本的对应关系。注意查看版本autogluon V0.4需要3.8或者3.9和3.10,pip版…...

10、Java继承与多态 - 内部类的概念与分类 1

10、Java继承与多态 - 内部类的概念与分类 1 什么是内部类? 如果一个事物的内部包含另一个事物,那么这就是一个内部包含另一个类,称作内部类; 例如:身体和心脏的关系,又如 -> 汽车和发动机的关系&#x…...

Java SE 面试题

文章目录 Java SE 面试题基本知识请简要介绍 Java SE。请解释 Java 的垃圾回收机制。请解释 Java 中的访问修饰符。 面向对象请解释封装、继承和多态。请解释接口和抽象类的区别。 集合框架请解释 ArrayList 和 LinkedList 的区别。请解释 Set 和 Map 接口。 异常处理请解释 Ja…...

Linux 之十九 编译工具链、.MAP 文件、.LST 文件

.map 文件和 .lst 文件是嵌入式开发中最有用的俩调试辅助文件。现在主要从事 RISC-V 架构,开始与 GCC 打交道,今天就重点学习一下 GCC 的 .map 文件、.lst 文件,并辅助以 ARMCC 和 IAR 作为对比。 编译工具链 .map 文件和 .lst 文件都是由编…...

小 C 的数学(math)

祝大家劳动节快乐!!小手动起来 言归正传┏ (゜ω゜)☞ 题目描述 小 C 想要成为一名 OIer,于是他提前学习数学,为 OI 做好铺垫。这一天,他的数学老师给了一道题:给定正整数 a,以及给定一个区间 …...

应用运行环境实时洞察,亚马逊云科技Cisco AppDynamics展优势

Cisco AppDynamics(APM)产品,现已正式上线亚马逊云科技Marketplace(中国区域)。可以通过亚马逊云科技Marketplace(中国区域)网站,灵活便捷地部署该解决方案,以便充分利用云原生APM(应用性能管理…...

C++程序设计——lambda表达式

一、问题引入 在C98中,如果想对一个数据集合中的元素进行排序,可以使用sort()方法,但如果待排序元素为自定义类型,就需要用户自己定义排序时的比较规则。 随着C语法的发展,人们开始觉得其编写比较复杂,每次…...

学习如何聚合零样本大型语言模型代理以进行企业披露分类

摘要本文研究一个轻量级训练聚合器是否能够将多样化的零样本大语言模型判断整合为更强的下游信号,用于公司披露分类。零样本大语言模型无需针对特定任务进行微调即可阅读披露文本,但其预测结果常因提示词、推理方式和模型家族的不同而存在差异。我采用一…...

OpenClaw内存优化:nanobot在4GB设备运行大型文档处理

OpenClaw内存优化:nanobot在4GB设备运行大型文档处理 1. 当4GB内存遇上100页PDF:一个不可能完成的任务? 上周我接到一个需求:需要在本地处理一份100页的技术文档PDF,提取关键信息并生成摘要。我的工作机是一台老旧的…...

精读《Harness design for long-running application development》:真正拉开差距的,不是模型本身,而是你怎么给它harness

精读《Harness design for long-running application development》:真正拉开差距的,不是模型本身,而是你怎么给它搭脚手架 原文:Harness design for long-running application development Anthropic 这篇文章最值得读的地方&a…...

【AI工程化硬核考点】:FastAPI 2.0 + async/await + StreamingResponse三重协程调度机制精讲

第一章:FastAPI 2.0 异步 AI 流式响应 面试题汇总FastAPI 2.0 原生强化了对异步流式响应(StreamingResponse)的支持,尤其适用于大语言模型(LLM)推理、实时日志推送、AI 生成内容分块返回等场景。面试官常聚…...

Science重磅指南:如何打造高影响力论文摘要?附Abstract写作黄金法则!

1. 科学论文摘要的黄金结构 写论文摘要就像给陌生人讲一个精彩的故事——要在短短200字内让人眼前一亮。我在Nature和Science上发过几篇论文,也审过上百篇投稿,发现顶级期刊的摘要其实有套"万能公式"。这个公式的核心是把摘要拆解成7个关键部分…...

RK3568 NPU RKNN(五):RKNN-ToolKit2性能与内存评估实战解析

1. 环境准备与工具链搭建 在开始RKNN-ToolKit2的性能与内存评估之前,我们需要先搭建完整的开发环境。这里以野火LubanCat开发板为例,具体硬件配置为RK3568芯片4GB内存版本。开发主机建议使用Ubuntu 20.04系统,确保Python版本在3.6-3.8之间。 …...

SOLIDWORKS Simulation实战:带孔矩形板拓扑优化全流程解析(附避坑指南)

SOLIDWORKS Simulation实战:带孔矩形板拓扑优化全流程解析(附避坑指南) 在机械设计领域,轻量化与结构强度往往是一对矛盾体。如何在保证零件功能的前提下最大限度减少材料使用?拓扑优化技术给出了完美答案。作为SOLIDW…...

3个核心功能:从效率瓶颈到资源整合的高效管理与智能处理指南

3个核心功能:从效率瓶颈到资源整合的高效管理与智能处理指南 【免费下载链接】douyin-downloader 项目地址: https://gitcode.com/GitHub_Trending/do/douyin-downloader 一、核心价值解析:短视频下载工具的技术突破与应用价值 1.1 多平台适配能…...

STM32温湿度监控系统设计与实现

## 1. 工业生产线温湿度监控系统设计### 1.1 系统架构设计 基于STM32F103C8T6微控制器的工业级温湿度监控系统采用三层架构: - **感知层**:3个DHT22数字温湿度传感器 - **控制层**:STM32F103C8T6最小系统板 - **云平台层**:ESP826…...

告别重复造轮子,用快马AI一键生成高复用登录组件提升效率

在开发官网登录入口时,我们常常需要重复处理用户认证、表单验证、状态管理等基础逻辑。这些工作虽然不复杂,但每次从零开始确实会消耗不少时间。最近我发现用InsCode(快马)平台可以快速生成高质量的登录组件,大大提升了开发效率。 组件功能设…...