springboot整合RabbitMQ的简单使用,一看即会

RabbitMQ在springboot中使用起来非常简单,如果不涉及到一些高级场景的使用,只需要非常少的配置。springboot提供了spring-boot-starter-amqp对消息的各种支持。

使用

我们知道,RabbitMQ把消息发送给队列时有四种消息路由策略:

  • direct(直连)
  • fanout(分发)
  • topic (主题)
  • headers(头部)

我们来看看最常用的direct、fanout、topic在springboot中如何使用。

创建工程,添加对应依赖:
在这里插入图片描述
工程创建后,pom.xml的依赖:

	<dependencies>
		<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>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.amqp</groupId>
			<artifactId>spring-rabbit-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

然后在application.yml中配置RabbitMQ的基本信息:

spring:
  rabbitmq:
    #默认地址localhost
    host: 192.168.56.101
    #默认端口5672
    port: 5672
    username: guest
    password: guest

所有可以配置的信息都在RabbitProperties类中看到:
在这里插入图片描述
接下来使用direct exchange(直连交换机)。

direct exchange

创建DirectConfig类配置相关队列等信息:

package com.xsw.springbootrabbitmqtest.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;

@Configuration
public class DirectConfig {
    //创建直连交换机
    @Bean
    public DirectExchange directExchangeTest(){
        return new DirectExchange("directExchangeTest",true,false);
    }
    //创建队列
    @Bean
    public Queue directQueueTest(){
        /*
        参数:
            name:       队列名
            durable:    是否持久化
            exclusive:  排他性,是否只有当前连接可用
            autoDelete: 没有生产者和消费者使用此队列时,是否自动删除队列 
         */
        return new Queue("directQueueTest",true,false,false);
    }

    //绑定
    @Bean
    public Binding binding(){
        return BindingBuilder.bind(directQueueTest()).to(directExchangeTest()).with("routingkey");
    }
}

创建Send类发送消息到名为“directExchangeTest”的交换机:

package com.xsw.springbootrabbitmqtest;

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

@Component
public class Send {
	//RabbitTemplate是springboot为我们封装好的操作消息的类
    @Autowired
    RabbitTemplate rabbitTemplate;

    public void send(){
        rabbitTemplate.convertAndSend("directExchangeTest","routingkey","hello direct");
        System.out.println("已发送消息");
    }
}

在测试类中运行发送消息的方法:

package com.xsw.springbootrabbitmqtest;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.Collection;
import java.util.Map;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootRabbitmqtestApplicationTests {
	
	@Autowired
	Send send;

	@Test
	public void test(){
		send.send();
	}

}

可以看到控制台:
在这里插入图片描述
此时,可以去RabbitMQ管理界面查看消息是否发送服务器:
在这里插入图片描述
在这里插入图片描述
可以看到的是,消息已经发送到RabbitMQ了(没有消费者监听队列,还没有消费消息)。

创建Recv类用于接收消息:

package com.xsw.springbootrabbitmqtest;


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

@Component
@RabbitListener(queues = "directQueueTest") //添加@RabbitListner注解监听“directQueueTest”队列
public class Recv {

    @RabbitHandler
    public void test(String message){
        System.out.println(message);
    }

}

接下来运行springboot主程序,看消费者是否收到了消息:
在这里插入图片描述
可以看到,控制台打印了消费者接收到的之前推送的消息。

fanout exchange

再来看看fanout交换机的使用,创建FanoutConfig:

package com.xsw.springbootrabbitmqtest.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;

@Configuration
public class FanoutConfig {
    //创建名为fanoutExchangeTest的交换机
    @Bean
    public FanoutExchange fanoutExchangeTest(){
        return new FanoutExchange("fanoutExchangeTest",true,false);
    }

    //创建三个队列用于测试
    @Bean
    public Queue queue1(){
        return new Queue("queue1",true,false,false);
    }
    @Bean
    public Queue queue2(){
        return new Queue("queue2",true,false,false);
    }
    @Bean
    public Queue queue3(){
        return new Queue("queue3",true,false,false);
    }
    //将三个队列绑定到交换机
    @Bean
    public Binding binding1(){
        return BindingBuilder.bind(queue1()).to(fanoutExchangeTest());  //这里不用路由键,因为在fanout路由规则下路由键会被忽略
    }
    @Bean
    public Binding binding2(){
        return BindingBuilder.bind(queue2()).to(fanoutExchangeTest());  //这里不用路由键,因为在fanout路由规则下路由键会被忽略
    }
    @Bean
    public Binding binding3(){
        return BindingBuilder.bind(queue3()).to(fanoutExchangeTest());  //这里不用路由键,因为在fanout路由规则下路由键会被忽略
    }
}

接下来创建FanoutSend类:

@Component
public class FanoutSend {
    
    @Autowired
    RabbitTemplate rabbitTemplate;
    
     public void send(){
        rabbitTemplate.convertAndSend("fanoutExchangeTest",null,"hello fanout");
        System.out.println("发送消息");
    }
}

在测试类中发送消息:

	@Test
	public void test(){
//		send.send();
		fanoutSend.send();
	}

在这里插入图片描述
消息发送成功,创建3个消费者接收消息,FanoutRecv1.java:

/*
监听队列:queue1
 */
@Component
@RabbitListener(queues = "queue1")
public class FanoutRecv1 {
    @RabbitHandler
    public void test(String message){
        System.out.println("FanoutRecvq received message:"+message);
    }
}

FanoutRecv2.java:


/*
监听队列:queue2
 */
@Component
@RabbitListener(queues = "queue2")
public class FanoutRecv2 {
    @RabbitHandler
    public void test(String message){
        System.out.println("FanoutRecv2 received message:"+message);
    }
}

FanoutRecv3.java:

@Component
@RabbitListener(queues = "queue3")
public class FanoutRecv3 {
    @RabbitHandler
    public void Test(String message){
        System.out.println("FanoutRecv3 received message:"+message);
    }
}

运行springboot主程序,可以看到控制台:
在这里插入图片描述
可以看到只要发送到 fanoutExchange 这个分发交换机的消息, 三个队列都绑定这个交换机,所以三个消息接收类都监听到了这条消息。

topic

接下来使用topic exchange,创建TopicConfig类:

@Configuration
public class TopicConfig {
    @Bean
    public TopicExchange topicExchangeTest(){
        return new TopicExchange("topicExchangeTest");
    }
    @Bean
    public Queue queueA(){
        return new Queue("queue_a");
    }
    @Bean
    public Queue queueB(){
        return new Queue("queue_b");
    }
    @Bean
    public Queue queueC(){
        return new Queue("queue_c");
    }

    @Bean
    public Binding bindingA(){
        //将队列a绑定到topicExchangeTest交换机,绑定的路由键为#.news,这样凡是消息携带的路由键以news结尾都会推送到该队列中
        return BindingBuilder.bind(queueA()).to(topicExchangeTest()).with("#.news");
    }
    @Bean
    public Binding bindingB(){
        //将队列b绑定到交换机,绑定的路由键为china.#,这样凡是消息携带的路由键以China开头都会推送到该队列中
        return BindingBuilder.bind(queueB()).to(topicExchangeTest()).with("china.#");
    }
    @Bean
    public Binding bindingC(){
        //usa.#表示会把与usa相关的信息推送队列
        return BindingBuilder.bind(queueC()).to(topicExchangeTest()).with("usa.#");
    }
}

创建TopicSend类发送消息:

@Component
public class TopicSend {

    @Autowired
    RabbitTemplate rabbitTemplate ;

    public void sendChinaNews(){
        rabbitTemplate.convertAndSend("topicExchangeTest","china.news","欢迎订阅中国新闻");
    }
    public void sendUsaNews(){
        rabbitTemplate.convertAndSend("topicExchangeTest","usa.news","欢迎订阅美国新闻");
    }
}

在测试类中发送路由键为china.new的消息:

	@Test
	public void test(){
//		send.send();
//		fanoutSend.send();
		topicSend.sendChinaNews();
	}

接着创建3个类用于监听3个队列
TopicRecv1.java:


/*
监听名为queue_a的队列
 */
@Component
@RabbitListener(queues = "queue_a")
public class TopicRecv1 {
    @RabbitHandler
    public void test(String message){
        System.out.println("TopicRecv1 接收到了路由键为 #.news 的消息:"+message);
    }
}

TopicRecv2.java


/*
监听名为queue_b的队列
 */
@Component
@RabbitListener(queues = "queue_b")
public class TopicRecv2 {
    @RabbitHandler
    public void test(String message){
        System.out.println("TopicRecv2 接收到了路由键为 china.# 的消息:"+message);
    }
}

TopicRecv3.java

/*
监听名为queue_c的队列
 */
@Component
@RabbitListener(queues = "queue_c")
public class TopicRecv3 {
    @RabbitHandler
    public void test(String message){
        System.out.println("TopicRecv3 接收到了路由键为 usa.# 的消息:"+message);
    }
}

接下来,运行springboot主程序,控制台输出:
在这里插入图片描述
可以看到TopicRecv1和TopicRecv2都收到了消息,只有TopicRecv3没有收到,因为他只订阅usa相关的消息。

继续在测试类中发送路由键为usa.#的消息:


	@Test
	public void test(){
//		send.send();
//		fanoutSend.send();
//		topicSend.sendChinaNews();
		topicSend.sendUsaNews();
	}

可以看到控制台输出:
在这里插入图片描述
此时,TopicRecv1和TopicRecv3接收到了消息,只有TopicRecv2没有接收到消息,因为他只订阅了china相关的消息。

总结:以上就是简单的使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值