RabbitMQ整合springboot

上节我们讲了rabbitmq的概念,原理,5种模式已经分别与Java进行整合,这节我们讲rabbitmq与springboot进行整合。(要提前准备好一个spring项目的基本框架)

整合时有两种方式创建交换机,队列及他们的绑定关系
1.添加配置类(加上@Configuration注解和@Bean注解)(topic模式,direct模式使用,也需要用到@RabbitListener,只起监听队列的作用)
2.用注解创建(@RabbitListener,注解中的内容比之增加,用来创建交换机,队列及他们的绑定关系,以及监听队列)

fanout模式

1.引入依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency>

然后在spring项目中创建两个模块,一个生产者模块,一个消费者模块

2.在yml/properties文件进行相应的配置

分别在两个模块中都进行创建

server: port:8080 spring: application: name:RabbitMQ-demo #rabbitmq配置 rabbitmq: username: guest password: guest virtual-host:/ host:127.0.0.1 port:5672

3.创建配置类(创建相应的交换机与队列,且绑定关系)

分别在两个模块中都进行创建(防止一方没有配置类启动时报错

packagecom.lx.producer.config;importorg.springframework.amqp.core.Binding;importorg.springframework.amqp.core.BindingBuilder;importorg.springframework.amqp.core.FanoutExchange;importorg.springframework.amqp.core.Queue;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;@ConfigurationpublicclassRabbitMqConfiguration{//创建一个fanout类型的交换机@BeanpublicFanoutExchangefanoutExchange(){//第一个参数是交换机的名字,第二个是是否持久化,第三个是是否自动删除returnnewFanoutExchange("fanout_order_exchange",true,false);}//创建三个队列@BeanpublicQueuesmsQueue(){returnnewQueue("sms.fanout.queue",true);}@BeanpublicQueueduanxinQueue(){returnnewQueue("duanxin.fanout.queue",true);}@BeanpublicQueueemailQueue(){returnnewQueue("email.fanout.queue",true);}//三个队列分别进行绑定关系@BeanpublicBindingsmsBinding(){returnBindingBuilder.bind(smsQueue()).to(fanoutExchange());}@BeanpublicBindingduanxinBinding(){returnBindingBuilder.bind(duanxinQueue()).to(fanoutExchange());}@BeanpublicBindingemailBinding(){returnBindingBuilder.bind(emailQueue()).to(fanoutExchange());}}

4.编写业务代码

在生产者模块中的service层中创建相应的生产信息业务类

packagecom.lx.producer.service;importjakarta.annotation.Resource;importorg.springframework.amqp.rabbit.core.RabbitTemplate;importorg.springframework.stereotype.Service;importjava.sql.SQLOutput;importjava.util.UUID;@ServicepublicclassOrderService{@ResourceRabbitTemplate rabbitTemplate;publicvoidmakeOrder(String userId,String productId,Integer numbers){String orderId=UUID.randomUUID().toString();System.out.println("订单生产成功:"+orderId);//通过MQ完成消息的发送String exchangeName="fanout_order_exchange";String routingKey=""; rabbitTemplate.convertAndSend(exchangeName,routingKey,orderId);}}

在消费者模块中创建3个相应的消费信息业务类
(注意:必须要在类上写上@RabbitListener注解,表示监听某个队列)

packagecom.lx.consumer.service;importorg.springframework.amqp.rabbit.annotation.RabbitHandler;importorg.springframework.amqp.rabbit.annotation.RabbitListener;importorg.springframework.stereotype.Service;@Service@RabbitListener(queues ={"duanxin.fanout.queue"})publicclassFanoutDuanxinConsumer{@RabbitHandlerpublicvoidreceiveMessage(String message){System.out.println("duanxin.fanout---接收到的信息是:"+message);}}
packagecom.lx.consumer.service;importorg.springframework.amqp.rabbit.annotation.RabbitHandler;importorg.springframework.amqp.rabbit.annotation.RabbitListener;importorg.springframework.stereotype.Service;@Service@RabbitListener(queues ={"email.fanout.queue"})publicclassFanoutEmailConsumer{@RabbitHandlerpublicvoidreceiveMessage(String message){System.out.println("email.fanout---接收到的信息是:"+message);}}
packagecom.lx.consumer.service;importorg.springframework.amqp.rabbit.annotation.RabbitHandler;importorg.springframework.amqp.rabbit.annotation.RabbitListener;importorg.springframework.stereotype.Service;@Service@RabbitListener(queues ={"sms.fanout.queue"})publicclassFanoutSmsConsumer{@RabbitHandlerpublicvoidreceiveMessage(String message){System.out.println("sms.fanout---接收到的信息是:"+message);}}

最后先启动rabbitmq,在启动两个项目,我们就能得到再消费者中得到生产者发送的消息了

direct模式

direct模式与fanout模式的代码差不多,只是要把配置类和生产者的业务处理类修改一下

配置类修改如下(把刚刚fanout命名都改为direct了)

packagecom.lx.producer.config;importorg.springframework.amqp.core.*;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;@ConfigurationpublicclassRabbitMqConfiguration{//创建一个direct类型的交换机@BeanpublicDirectExchangedirectExchangeExchange(){//第一个参数是交换机的名字,第二个是是否持久化,第三个是是否自动删除returnnewDirectExchange("direct_order_exchange",true,false);}//创建三个队列@BeanpublicQueuesmsQueue(){returnnewQueue("sms.direct.queue",true);}@BeanpublicQueueduanxinQueue(){returnnewQueue("duanxin.direct.queue",true);}@BeanpublicQueueemailQueue(){returnnewQueue("email.direct.queue",true);}//三个队列分别进行绑定关系@BeanpublicBindingsmsBinding(){returnBindingBuilder.bind(smsQueue()).to(directExchangeExchange()).with("sms");}@BeanpublicBindingduanxinBinding(){returnBindingBuilder.bind(duanxinQueue()).to(directExchangeExchange()).with("duanxin");}@BeanpublicBindingemailBinding(){returnBindingBuilder.bind(emailQueue()).to(directExchangeExchange()).with("email");}}

改成穿件direct类型的交换机以及路由与队列绑定时加了key

生产者业务类

packagecom.lx.producer.service;importjakarta.annotation.Resource;importorg.springframework.amqp.rabbit.core.RabbitTemplate;importorg.springframework.stereotype.Service;importjava.sql.SQLOutput;importjava.util.UUID;@ServicepublicclassOrderService{@ResourceRabbitTemplate rabbitTemplate;publicvoidmakeOrder(String userId,String productId,Integer numbers){String orderId=UUID.randomUUID().toString();System.out.println("订单生产成功:"+orderId);//通过MQ完成消息的发送String exchangeName="direct_order_exchange";String routingKey1="sms";String routingKey2="duanxin"; rabbitTemplate.convertAndSend(exchangeName,routingKey1,orderId); rabbitTemplate.convertAndSend(exchangeName,routingKey2,orderId);}}

其余的代码不要变,把所有名字从fanout改为direct就行

topic模式

topic模式中我们使用注解的方式来创建交换机,队列以及它们之间的绑定关系,只需要把消费者业务代码及生产者业务代码修改下即可

消费者业务代码(修改@RabbitListener注解)

packagecom.lx.consumer.service;importorg.springframework.amqp.core.ExchangeTypes;importorg.springframework.amqp.rabbit.annotation.*;importorg.springframework.stereotype.Service;@Service@RabbitListener(bindings =@QueueBinding( value =@Queue(value ="duanxin.topic.queue",durable ="true",autoDelete ="false"), exchange =@Exchange(value ="topic_order_exchange",type =ExchangeTypes.TOPIC), key ="#.duanxin.#"))publicclassTopicDuanxinConsumer{@RabbitHandlerpublicvoidreceiveMessage(String message){System.out.println("duanxin.topic---接收到的信息是:"+message);}}
packagecom.lx.consumer.service;importorg.springframework.amqp.core.ExchangeTypes;importorg.springframework.amqp.rabbit.annotation.*;importorg.springframework.stereotype.Service;@Service@RabbitListener(bindings =@QueueBinding( value =@Queue(value ="topic.email.queue",durable ="true",autoDelete ="false"), exchange =@Exchange(value ="topic_order_exchange",type =ExchangeTypes.TOPIC), key ="*.email.#"))publicclassTopicEmailConsumer{@RabbitHandlerpublicvoidreceiveMessage(String message){System.out.println("email.direct---接收到的信息是:"+message);}}
packagecom.lx.consumer.service;importorg.springframework.amqp.core.ExchangeTypes;importorg.springframework.amqp.rabbit.annotation.*;importorg.springframework.stereotype.Service;@Service@RabbitListener(bindings =@QueueBinding( value =@Queue(value ="sms.topic.queue",durable ="true",autoDelete ="false"), exchange =@Exchange(value ="topic_order_exchange",type =ExchangeTypes.TOPIC), key ="com.#"))publicclassTopicSmsConsumer{@RabbitHandlerpublicvoidreceiveMessage(String message){System.out.println("sms.direct---接收到的信息是:"+message);}}

生产者业务代码(只修改routing keyj就行,通配符模式)

packagecom.lx.producer.service;importjakarta.annotation.Resource;importorg.springframework.amqp.rabbit.core.RabbitTemplate;importorg.springframework.stereotype.Service;importjava.sql.SQLOutput;importjava.util.UUID;@ServicepublicclassOrderService{@ResourceRabbitTemplate rabbitTemplate;publicvoidmakeOrder(String userId,String productId,Integer numbers){String orderId=UUID.randomUUID().toString();System.out.println("订单生产成功:"+orderId);//通过MQ完成消息的发送String exchangeName="topic_order_exchange";String routingKey1="com.email.duanxin";// String routingKey2="duanxin"; rabbitTemplate.convertAndSend(exchangeName,routingKey1,orderId);// rabbitTemplate.convertAndSend(exchangeName,routingKey2,orderId);}}

Read more

SpringBoot+Vue web药店管理系统平台完整项目源码+SQL脚本+接口文档【Java Web毕设】

SpringBoot+Vue web药店管理系统平台完整项目源码+SQL脚本+接口文档【Java Web毕设】

系统架构设计### 摘要 随着信息技术的飞速发展,传统药店管理模式逐渐暴露出效率低下、数据管理混乱等问题。药店在日常运营中涉及药品库存管理、销售记录、客户信息等多方面数据,传统的人工记录方式不仅耗时耗力,还容易出现错误。为了提高药店的管理效率和服务质量,开发一套基于现代Web技术的药店管理系统显得尤为重要。该系统能够实现药品信息的数字化管理,优化库存流转,提升销售效率,并为用户提供便捷的查询和购买体验。关键词:药店管理、数字化、效率提升、SpringBoot、Vue。 本系统采用前后端分离架构,后端基于SpringBoot框架实现,提供RESTful API接口,前端使用Vue.js框架构建用户界面,确保系统的高效性和可扩展性。系统主要功能包括药品信息管理、库存监控、销售记录统计、会员管理以及数据报表生成等。通过Spring Security实现用户权限控制,确保数据安全性;利用MyBatis作为持久层框架,优化数据库操作效率。系统还提供了完善的接口文档,便于后续功能扩展和维护。关键词:SpringBoot、Vue.js、RESTful API、权限控制、MyBatis。 数据表

By Ne0inhk
JAVA 异常处理:从原理到实战最佳实践

JAVA 异常处理:从原理到实战最佳实践

JAVA 异常处理:从原理到实战最佳实践 1.1 本章学习目标与重点 💡 掌握异常的分类与核心概念,理解异常处理的设计思想。 💡 熟练运用 try-catch-finally、throws、throw 处理异常。 💡 掌握自定义异常的编写与使用场景,规范异常处理流程。 ⚠️ 本章重点是 异常处理的最佳实践 和 避免常见误区,这是提升代码健壮性的核心技能。 1.2 异常的核心概念与分类 1.2.1 什么是异常 💡 异常是指程序运行过程中出现的非正常情况,它会中断程序的正常执行流程。 比如文件找不到、数组下标越界、空指针访问等,这些情况都会触发异常。 Java 中所有异常都是 Throwable 类的子类,异常处理的本质是捕获并处理这些非正常情况,保证程序可以继续运行或优雅退出。 1.2.2 异常的分类 Java 中的异常体系分为三大类,它们的父类都是 Throwable: * 是 JVM 内部的严重错误,

By Ne0inhk
Java中的char、String、StringBuilder与StringBuffer 深度详解

Java中的char、String、StringBuilder与StringBuffer 深度详解

文章目录 * 第一章:一切的基础——char原始类型 * 1.1 定义与本质 * 1.2 字符编码的演变:从char到byte * 1.3 char的初始化与赋值 * 1.4 char的运算 * 第二章:不可变的字符串——String类 * 2.1 类的定义与不可变性 * 2.2 不可变性的优势 * 2.3 创建String对象的两种方式 * 2.4 操作的真相:总是生成新对象 * 2.5 字符串拼接的陷阱与优化 * 第三章:可变的字符序列——StringBuilder与StringBuffer * 3.1 AbstractStringBuilder:共同的祖先 * 3.2 StringBuilder:非线程安全的“快枪手” * 3.3

By Ne0inhk
本地 AI 模型管理新选择:OpenWebUI+cpolar 让远程使用更自由

本地 AI 模型管理新选择:OpenWebUI+cpolar 让远程使用更自由

OpenWebUI 是一款能将本地 AI 模型操作可视化的工具,支持管理 Ollama 本地模型和接入 OpenAI 兼容 API,还有私人知识库、多用户管理等功能,不管是设计师、小团队成员还是学生党都能用。它把命令行操作变成类似微信聊天的界面,操作简单,数据存在本地,隐私有保障。 用下来发现,OpenWebUI 的交互体验很流畅,打字机效果、Markdown 渲染这些细节做得不错,新手也能快速上手管理模型。不过要注意,运行大模型时对电脑内存要求不低,至少得 8GB 以上,不然可能卡顿。 但它有个局限,默认只能在局域网内使用。比如设计师在家调好的模型,上班想继续用就得远程操控电脑,很不方便;小团队成员不在同一局域网,就没法共用模型协作。 这时候搭配 cpolar 就不一样了。cpolar 能实现内网穿透,让 OpenWebUI 突破局域网限制,出门在外用手机浏览器输入网址就能访问,还能轻松分享给朋友体验,数据传输加密也更安全,不用额外买服务器,

By Ne0inhk