RabbitMQ3/7--springboot集成RabbitMQ

交换机与队列进行绑定的方式

1.配置类config(消费者端和生产者端)推荐
2.注解(在消费者端使用@RabbitListener(bindings = @QueueBinding()进行绑定)
3.页面绑定(不推荐)

springboot整合RabbitMQ

业务场景,模拟用户下单,交换机进行消息分发

在这里插入图片描述
生产者和消费者分属不同的模块

工程架构

在这里插入图片描述

Fanout 模式(交换机与队列绑定在生产者端)

引入依赖项

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

配置文件application.yml

# 服务端口
server:
  port: 8080
# 配置rabbitmq服务
spring:
  rabbitmq:
    username: ems
    password: ems
    virtual-host: /ems
    host: 39.105.×××  //阿里云服务器地址,先开端口号
    port: 5672

生产者

service发送消息
package com.yhd.rabbitmq.service;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.UUID;

/**
 * @author 袁浩东
 * @description
 * @date 2021/7/20 20:53
 */
@Service
public class OrderService {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void makeOrder(String userid,String productid,int num){
        //1.根据商品id查询库存是否足够
        //2.保存订单
        String orderId = UUID.randomUUID().toString();
        System.out.println("订单生产成功:"+orderId);
        //3.通过MQ来完成消息的分发
        //参数1:交换机 参数2:路由key/queue队列名称 参数3:消息内容
        String exchangeName = "fanout_order_exchange";
        String routingKey = "";
        rabbitTemplate.convertAndSend(exchangeName,routingKey,orderId);
    }
}
使用配置类完成交换机和队列的绑定关系
package com.yhd.rabbitmq.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author 袁浩东
 * @description
 * @date 2021/7/20 20:56
 */
@Configuration
public class RabbitMqConfiguration {
    //1.声明注册fanout模式的交换机
    @Bean
    public FanoutExchange fanoutExchange(){
        //参数1,交换机名字 参数2,交换机是否持久化 参数3,是否自动删除
        return new FanoutExchange("fanout_order_exchange",true,false);
    }
    //2.声明3个队列
    @Bean
    public Queue smsQueue(){
        //参数1,队列名称 参数2,是否持久化
        return new Queue("sms.fanout.queue",true);
    }
    @Bean
    public Queue duanxinQueue(){
        return new Queue("duanxin.fanout.queue",true);
    }
    @Bean
    public Queue emailQueue(){
        return new Queue("email.fanout.queue",true);
    }
    //3.完成队列和交换机的绑定关系
    @Bean
    public Binding smsBingding(){
        return BindingBuilder.bind(smsQueue()).to(fanoutExchange());
    }
    @Bean
    public Binding duanxinBingding(){
        return BindingBuilder.bind(duanxinQueue()).to(fanoutExchange());
    }
    @Bean
    public Binding emailBingding(){
        return BindingBuilder.bind(emailQueue()).to(fanoutExchange());
    }
}
测试类注入并调用
package com.yhd.rabbitmq;

import com.yhd.rabbitmq.service.OrderService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class RabbitmqApplicationTests {
    @Autowired
    private OrderService orderService;
    @Test
    void contextLoads() {
        orderService.makeOrder("1","1",12);
    }
}
运行结果
  • 队列
  • 在这里插入图片描述
交换机

在这里插入图片描述

队列中的绑定交换机的信息

在这里插入图片描述

消费者

依赖项
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
配置文件application.yml
# 服务端口
server:
  port: 8081  //避免端口号冲突
# 配置rabbitmq服务
spring:
  rabbitmq:
    username: ems
    password: ems
    virtual-host: /ems
    host: 39.105.××××
    port: 5672
消息监听并进行消费(短信,Email,SMS三个消费者)
短信
package com.yhd.rabbitmq.service.fanout;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * @author 袁浩东
 * @description
 * @date 2021/7/20 22:15
 */
//spring 容器托管`在这里插入代码片`
@Component
//声明消费者,并绑定队列
@RabbitListener(queues = "duanxin.fanout.queue")
public class FanoutDuanxinConsumer {
    @RabbitHandler  //回调,message就是消息内容
    public void reviceMessage(String message){
        System.out.println("duanxin接收到了的订单信息是:"+message);
    }
}
Email
package com.yhd.rabbitmq.service.fanout;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * @author 袁浩东
 * @description
 * @date 2021/7/20 22:17
 */
@Component
@RabbitListener(queues = "email.fanout.queue")
public class FanoutEmailConsumer {
    @RabbitHandler
    public void reviceMessage(String message){
        System.out.println("email接收到了的订单信息是:"+message);
    }
}
SMS
package com.yhd.rabbitmq.service.fanout;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * @author 袁浩东
 * @description
 * @date 2021/7/20 22:17
 */
@Component
@RabbitListener(queues = "sms.fanout.queue")
public class FanoutSMSConsumer {
    @RabbitHandler
    public void reviceMessage(String message){
        System.out.println("sms接收到了的订单信息是:"+message);
    }
}
运行结果

在这里插入图片描述
消息队列中的消息已经被消费掉了
在这里插入图片描述

总结

生产者:使用service完成消息发送,使用config配置类完成队列和交换机的绑定,使用测试类进行测试
消费者:声明为消费者,进行队列绑定,消息回调
在这里插入图片描述
步骤:
1.生产者声明交换机
2.生产者声明队列
3.生产者完成交换机与队列的绑定
4.消费者通过队列与生产者建立联系


Direct 模式(交换机与队列的绑定在消费者端)

Direct模式与Finout模式类似,仅多了一个路由key的绑定。故直接上代码

生产者

service

//模拟用户下单
public void makeOrderDirect(String userid,String productid,int num){
    //1.根据商品id查询库存是否足够
    //2.保存订单
    String orderId = UUID.randomUUID().toString();
    System.out.println("订单生产成功:"+orderId);
    //3.通过MQ来完成消息的分发
    //参数1:交换机 参数2:路由key/queue队列名称 参数3:消息内容
    String exchangeName = "direct_order_exchange";
    String routingKey = "";
    rabbitTemplate.convertAndSend(exchangeName,"email",orderId);
    rabbitTemplate.convertAndSend(exchangeName,"duanxin",orderId);
}

测试类

@Test
void testorderDerect() {
    orderService.makeOrderDirect("1","1",12);
}

消费者

交换机与队列的绑定(配置类)

package com.yhd.rabbitmq.config;

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 袁浩东
 * @description
 * @date 2021/7/20 22:53
 */
@Configuration
public class RabbitMqConfiguration {
    //1.声明注册direct模式的交换机
    @Bean
    public DirectExchange directExchange(){
        return new DirectExchange("direct_order_exchange",true,false);
    }
    //2.声明队列
    @Bean
    public Queue directSmsQueue(){
        return new Queue("sms.direct.queue",true);
    }
    @Bean
    public Queue driectDuanxinQueue(){
        return new Queue("duanxin.direct.queue",true);
    }
    @Bean
    public Queue driectEmailQueue(){
        return new Queue("email.direct.queue",true);
    }
    //3.完成绑定关系
    @Bean
    public Binding smsBingding(){
        return BindingBuilder.bind(directSmsQueue()).to(directExchange()).with("sms");
    }
    @Bean
    public Binding duanxinBingding(){
        return BindingBuilder.bind(driectDuanxinQueue()).to(directExchange()).with("duanxin");
    }
    @Bean
    public Binding emailBingding(){
        return BindingBuilder.bind(driectEmailQueue()).to(directExchange()).with("email");
    }
}

消息监听与消费(短信,Email,SMS)

短信
package com.yhd.rabbitmq.service.driect;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * @author 袁浩东
 * @description
 * @date 2021/7/20 22:15
 */
//spring 容器托管
@Component
//声明消费者,并绑定队列
@RabbitListener(queues = "duanxin.direct.queue")
public class DriectDuanxinConsumer {
    @RabbitHandler  //回调,message就是消息内容
    public void reviceMessage(String message){
        System.out.println("duanxin接收到了的订单信息是:"+message);
    }
}
Email
package com.yhd.rabbitmq.service.driect;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * @author 袁浩东
 * @description
 * @date 2021/7/20 22:17
 */
@Component
@RabbitListener(queues = "email.direct.queue")
public class DriectEmailConsumer {
    @RabbitHandler
    public void reviceMessage(String message){
        System.out.println("email接收到了的订单信息是:"+message);
    }
}
SMS
package com.yhd.rabbitmq.service.driect;

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * @author 袁浩东
 * @description
 * @date 2021/7/20 22:17
 */
@Component
@RabbitListener(queues = "sms.direct.queue")
public class DriectSMSConsumer {
    @RabbitHandler
    public void reviceMessage(String message){
        System.out.println("sms接收到了的订单信息是:"+message);
    }
}

运行结果

在这里插入图片描述

总结

在进行交换机与队列绑定的时候要进行路由key的设置
在这里插入图片描述


Topic 模式(注解绑定)

Topic模式与Direct模式类似,都需要绑定路由key从而完成消息的匹配与转发,不同之处在于,Topic模式使用通配符模式,更灵活。

生产者

service

//--------------------------topic--------------------------------
//模拟用户下单
public void makeOrderTopic(String userid,String productid,int num){
    //1.根据商品id查询库存是否足够
    //2.保存订单
    String orderId = UUID.randomUUID().toString();
    System.out.println("订单生产成功:"+orderId);
    //3.通过MQ来完成消息的分发
    //参数1:交换机 参数2:路由key/queue队列名称 参数3:消息内容
    String exchangeName = "topic_order_exchange";
    String routingKey = "com.duanxin";
    rabbitTemplate.convertAndSend(exchangeName,routingKey,orderId);
}

测试类

@Test
void testorderTopic() {
    orderService.makeOrderTopic("1","1",12);
}

消费者(短信,Email,SMS三个消费者)

短信

package com.yhd.rabbitmq.service.topic;

import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.stereotype.Component;

/**
 * @author 袁浩东
 * @description
 * @date 2021/7/20 22:15
 */
//spring 容器托管
@Component
//声明消费者,并绑定队列
@RabbitListener(bindings = @QueueBinding(
        value = @Queue(value = "duanxin.topic.queue",durable = "true",autoDelete  = "false"),
        exchange = @Exchange(value = "topic_order_exchange",type = ExchangeTypes.TOPIC),
        key = "#.duanxin.#"
) )
public class TopicDuanxinConsumer {
    @RabbitHandler  //回调,message就是消息内容
    public void reviceMessage(String message){
        System.out.println("duanxin接收到了的订单信息是:"+message);
    }
}

Email

package com.yhd.rabbitmq.service.topic;

import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.stereotype.Component;

/**
 * @author 袁浩东
 * @description
 * @date 2021/7/20 22:17
 */
@Component
@RabbitListener(bindings = @QueueBinding(
        value = @Queue(value = "email.topic.queue",durable = "true",autoDelete =  "false"),
        exchange = @Exchange(value = "topic_order_exchange",type = ExchangeTypes.TOPIC),
        key = "#.email.#"
))
public class TopciEmailConsumer {
    @RabbitHandler
    public void reviceMessage(String message){
        System.out.println("email接收到了的订单信息是:"+message);
    }
}

SMS

package com.yhd.rabbitmq.service.topic;

import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.stereotype.Component;

/**
 * @author 袁浩东
 * @description
 * @date 2021/7/20 22:17
 */
@Component
@RabbitListener(bindings = @QueueBinding(
        value = @Queue(value = "sms.topic.queue",durable = "true",autoDelete =  "false"),
        exchange = @Exchange(value = "topic_order_exchange",type = ExchangeTypes.TOPIC),
        key = "com.#"
))
public class TopicSMSConsumer {
    @RabbitHandler
    public void reviceMessage(String message){
        System.out.println("sms接收到了的订单信息是:"+message);
    }
}

运行结果

消费者启动后

在这里插入图片描述

生产者启动后

在这里插入图片描述

总结

使用注解进行交换机和队列的绑定
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值