rabbitmq使用springboot实现direct模式

一、 Direct模式

  • 类型:direct
  • 特点:Direct模式是fanout模式上的一种叠加,增加了路由RoutingKey的模式。

二、coding

Ⅰ 生产者 

1、引入相应的pom文件 pom.xml



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.1.5.RELEASE
         
    
    com.xpf
    rabbitmq-springboot
    0.0.1-SNAPSHOT
    rabbitmq-springboot
    Demo project for Spring Boot
    
        8
    
    
        
        
            org.springframework.boot
            spring-boot-starter-amqp
        
        
            org.springframework.boot
            spring-boot-starter-web
        
 
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            org.springframework.amqp
            spring-rabbit-test
            test
        
        
            org.junit.jupiter
            junit-jupiter
            RELEASE
            test
        
        
            org.junit.jupiter
            junit-jupiter-api
 
            test
        
    
 
 

2、配置文件 application.properties

server.port=8080
spring.rabbitmq.username=admin
spring.rabbitmq.password=admin
spring.rabbitmq.virtual-host=/
spring.rabbitmq.host=192.168.199.20
spring.rabbitmq.port=5672

3、写一个生产者 DirectOrderService.java

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

import java.util.UUID;

@Service
public class DirectOrderService {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 模拟用户下单,发送消息给下游系统
     * @param user
     * @param num
     */
    public void makerOrder(String user,  int num){
        //1、查询库存是否有剩余
        //2、保存订单
        String orderId = UUID.randomUUID().toString();
        System.out.println("订单生产成功:" + orderId);
        //3、通过mq给下游系统发送消息
        String exchangeName = "direct_order_exchange";
        rabbitTemplate.convertAndSend(exchangeName, "sms", orderId);
        rabbitTemplate.convertAndSend(exchangeName, "email", orderId);
        System.out.println("完成");
    }
}

(从代码中可以看到,direct_order_exchange交换机分别给绑定的路由key为sms和email的消息队列发送了消息)

4、写一个测试类,发送消息

import com.xpf.rabbitmqspringboot.service.DirectOrderService;
import com.xpf.rabbitmqspringboot.service.FanoutOrderService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class RabbitmqSpringbootApplicationTests {

    @Autowired
    private FanoutOrderService fanoutOrderService;

    @Autowired
    private DirectOrderService directOrderService;

    /**
     * Direct模式生产者发送消息
     */
    @Test
    public void setDirectOrderService(){
        directOrderService.makerOrder("用户2", 10);
    }
}

(先别启动测试类,因为交换机和队列的声明放在下面的消费者中。) 

 Ⅱ 消费者

1、新建一个springboot项目,其中pom.xml 和 application.properties和上述生产者文件相同,但是如果在一个电脑模拟同启动两个项目时,记得把application.properties中的端口换成不同的

2、使用springboot写一个配置文件 RabbitMqConfiguration.java

关于为啥在消费者中建配置文件而不是在生产者,请看rabbitmq使用springboot实现fanout模式_p&f°的博客-CSDN博客

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitMqConfiguration {

    //1、声明注册Direct模式交换机
    @Bean
    public DirectExchange DirectExchange(){
        return new DirectExchange("direct_order_exchange", true, false);
    }

    //2、声明队列 sms.Direct.queue、email.Direct.queue、duanxin.Direct.queue
    @Bean
    public Queue smsQueue(){
        return new Queue("sms.direct.queue", true);
    }

    @Bean
    public Queue emailQueue(){
        return new Queue("email.direct.queue", true);
    }

    @Bean
    public Queue duanxinQueue(){
        return new Queue("duanxin.direct.queue", true);
    }

    //3、完成绑定关系(队列绑定交换机)
    @Bean
    public Binding smsBinding(){
        return BindingBuilder.bind(smsQueue()).to(DirectExchange()).with("sms");
    }

    @Bean
    public Binding emailBinding(){
        return BindingBuilder.bind(emailQueue()).to(DirectExchange()).with("email");
    }

    @Bean
    public Binding duanxinBinding(){
        return BindingBuilder.bind(duanxinQueue()).to(DirectExchange()).with("duanxin");
    }
}

3、写三个消费者分别监听路由key为sms、email、duanxin的消息队列

(这里举例两个 SmsDirectConsumer.java 和 EmailDirectConsumer.java)

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

/**
 * @Author xpf
 * @Date 2023/7/9 1:27
 * @Version 1.0
 */
@Component
@RabbitListener(queues = "sms.direct.queue")
public class SmsDirectConsumer {

    @RabbitHandler
    public void receiveMessage(String message){
        System.out.println("接收到来自队列sms.direct.queue消息订单的message是:" + message);
    }
}
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * @Author xpf
 * @Date 2023/7/9 1:27
 * @Version 1.0
 */
@Component
@RabbitListener(queues = "email.direct.queue")
public class EmailDirectConsumer {

    @RabbitHandler
    public void receiveMessage(String message){
        System.out.println("接收到来自队列email.direct.queue消息订单的message是:" + message);
    }
}

三、测试

1、先启动消费者,因为本项目配置类在消费者

2、启动生产者测试类

结果发现路由key为sms、email的消息队列接收到了生产者发送的消息,而duanxin没有收到,结果符合预期

你可能感兴趣的:(rabbitmq,spring,boot,java-rabbitmq,rabbitmq)