150_SpringBoot案例-direct路由模式
目录
整体核心
目标
:::info
使用springboot完成rabbitmq的消费模式-direct
:::
实现步骤
:::info
1:创建生产者工程:sspringboot-rabbitmq-direct-producer
2:创建消费者工程:springboot-rabbitmq-direct-consumer
3:引入spring-boot-rabbitmq的依赖
4:进行消息的分发和测试
5:查看和观察web控制台的状况
:::
生产者
创建生产者工程:springboot-rabbitmq-direct-producer
在pom.xml中引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
在application.yml进行配置
# 服务端口
server:
port: 8080
# 配置rabbitmq服务
spring:
rabbitmq:
username: admin
password: admin
virtual-host: /
host: 47.104.141.27
port: 5672
定义订单的生产者
package com.xuexiangban.rabbitmq.springbootrabbitmqdirectproducer.service;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.UUID;
/**
* @author: 学相伴-飞哥
* @description: OrderService
* @Date : 2021/3/4
*/
@Component
public class OrderService {
@Autowired
private RabbitTemplate rabbitTemplate;
// 1: 定义交换机
private String exchangeName = "direct_order_exchange";
public void makeOrder(Long userId, Long productId, int num) {
// 1: 模拟用户下单
String orderNumer = UUID.randomUUID().toString();
// 2: 根据商品id productId 去查询商品的库存
// int numstore = productSerivce.getProductNum(productId);
// 3:判断库存是否充足
// if(num > numstore ){ return "商品库存不足..."; }
// 4: 下单逻辑
// orderService.saveOrder(order);
// 5: 下单成功要扣减库存
// 6: 下单完成以后
System.out.println("用户 " + userId + ",订单编号是:" + orderNumer);
// 发送订单信息给RabbitMQ direct
rabbitTemplate.convertAndSend(exchangeName, "email", orderNumer);
rabbitTemplate.convertAndSend(exchangeName, "sms", orderNumer);
rabbitTemplate.convertAndSend(exchangeName, "weixin", orderNumer);
}
}
绑定关系
:::info
绑定关系方式有两种:一种是配置类,一种是注解@RabbitListener(bindings =@QueueBinding
推荐使用配置类
生产者和消费者中只需要一边添加配置类就可以了,建议消费者中添加,因为通常消费者先启动
:::
package com.xuexiangban.rabbitmq.springbootrabbitmqdirectproducer.service;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Author : JCccc
* @CreateTime : 2019/9/3
* @Description :
**/
@Configuration
public class DirectRabbitConfig {
//队列
@Bean
public Queue emailQueue() {
// durable:是否持久化,默认是false,持久化队列:会被存储在磁盘上,当消息代理重启时仍然存在,暂存队列:当前连接有效
// exclusive:默认也是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。此参考优先级高于durable
// autoDelete:是否自动删除,当没有生产者或者消费者使用此队列,该队列会自动删除。
//一般设置一下队列的持久化就好,其余两个就是默认false
return new Queue("email.direct.queue", true);
}
@Bean
public Queue smsQueue() {
// durable:是否持久化,默认是false,持久化队列:会被存储在磁盘上,当消息代理重启时仍然存在,暂存队列:当前连接有效
// exclusive:默认也是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。此参考优先级高于durable
// autoDelete:是否自动删除,当没有生产者或者消费者使用此队列,该队列会自动删除。
//一般设置一下队列的持久化就好,其余两个就是默认false
return new Queue("sms.direct.queue", true);
}
@Bean
public Queue weixinQueue() {
// durable:是否持久化,默认是false,持久化队列:会被存储在磁盘上,当消息代理重启时仍然存在,暂存队列:当前连接有效
// exclusive:默认也是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。此参考优先级高于durable
// autoDelete:是否自动删除,当没有生产者或者消费者使用此队列,该队列会自动删除。
//一般设置一下队列的持久化就好,其余两个就是默认false
return new Queue("weixin.direct.queue", true);
}
//Direct交换机
@Bean
public DirectExchange directOrderExchange() {
return new DirectExchange("direct_order_exchange", true, false);
}
//绑定 将队列和交换机绑定
@Bean
public Binding bindingDirect1() {
return BindingBuilder.bind(weixinQueue()).to(directOrderExchange()).with("weixin");
}
@Bean
public Binding bindingDirect2() {
return BindingBuilder.bind(smsQueue()).to(directOrderExchange()).with("sms");
}
@Bean
public Binding bindingDirect3() {
return BindingBuilder.bind(emailQueue()).to(directOrderExchange()).with("email");
}
}
进行测试
package com.xuexiangban.rabbitmq.springbootrabbitmqdirectproducer;
import com.xuexiangban.rabbitmq.springbootrabbitmqdirectproducer.service.OrderService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class SpringbootRabbitmqDirectProducerApplicationTests {
@Autowired
OrderService orderService;
@Test
public void contextLoads() throws Exception {
for (int i = 0; i < 10; i++) {
Thread.sleep(1000);
Long userId = 100L + i;
Long productId = 10001L + i;
int num = 10;
orderService.makeOrder(userId, productId, num);
}
}
}
消费者
创建消费者工程:springboot-rabbitmq-direct-consumer
引入依赖pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
在application.yml进行配置
# 服务端口
server:
port: 8081
# 配置rabbitmq服务
spring:
rabbitmq:
username: admin
password: admin
virtual-host: /
host: 47.104.141.27
port: 5672
消费者 - 邮件服务
package com.xuexiangban.rabbitmq.springbootrabbitmqdirectconsumer.consumer;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.stereotype.Component;
// bindings其实就是用来确定队列和交换机绑定关系
@RabbitListener(bindings =@QueueBinding(
// email.direct.queue 是队列名字,这个名字你可以自定随便定义。
value = @Queue(value = "email.direct.queue",autoDelete = "false"),
// order.direct 交换机的名字 必须和生产者保持一致
exchange = @Exchange(value = "direct_order_exchange",
// 这里是确定的rabbitmq模式是:direct 是以路由模式
type = ExchangeTypes.DIRECT)
))
@Component
public class EmailService {
// @RabbitHandler 代表此方法是一个消息接收的方法。该不要有返回值
@RabbitHandler
public void messagerevice(String message){
// 此处省略发邮件的逻辑
System.out.println("email-------------->" + message);
}
}
消费者 - 短信服务
package com.xuexiangban.rabbitmq.springbootrabbitmqdirectconsumer.consumer;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.stereotype.Component;
// bindings其实就是用来确定队列和交换机绑定关系
@RabbitListener(bindings =@QueueBinding(
// email.direct.queue 是队列名字,这个名字你可以自定随便定义。
value = @Queue(value = "sms.direct.queue",autoDelete = "false"),
// order.fanout 交换机的名字 必须和生产者保持一致
exchange = @Exchange(value = "direct_order_exchange",
// 这里是确定的rabbitmq模式是:direct 是以路由模式
type = ExchangeTypes.DIRECT)
))
@Component
public class SMSService {
// @RabbitHandler 代表此方法是一个消息接收的方法。该不要有返回值
@RabbitHandler
public void messagerevice(String message){
// 此处省略发邮件的逻辑
System.out.println("sms-------------->" + message);
}
}
消费者 - 微信服务
package com.xuexiangban.rabbitmq.springbootrabbitmqdirectconsumer.consumer;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.stereotype.Component;
// bindings其实就是用来确定队列和交换机绑定关系
@RabbitListener(bindings =@QueueBinding(
// email.direct.queue 是队列名字,这个名字你可以自定随便定义。
value = @Queue(value = "weixin.direct.queue",autoDelete = "false"),
// order.direct 交换机的名字 必须和生产者保持一致
exchange = @Exchange(value = "direct_order_exchange",
// 这里是确定的rabbitmq模式是:direct 是以路由模式
type = ExchangeTypes.DIRECT)
))
@Component
public class WeixinService {
// @RabbitHandler 代表此方法是一个消息接收的方法。该不要有返回值
@RabbitHandler
public void messagerevice(String message){
// 此处省略发邮件的逻辑
System.out.println("weixin-------------->" + message);
}
}
启动服务SpringbootRabbitmqDirectConsumerApplication,查看效果
分类:
210_RabbitMQ
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?