文章目录
- 创建SpringBoot和RabbitMQ的整合项目
- 首先快速创建一个maven项目
- 引入SpringBoot整合rabbitMQ的依赖
- 在src/main目录下创建resources目录并引入配置文件
- 写消息发送者MessageSender
- 写消息接收者MessageReceiver
- 写RabbitMQConfig配置类
- 写SpringBoot启动主类
- CommandLineRunner接口的作用
- 启动程序 查看效果
- 注意要点
- 15672和5672的区别
- 消息发送的队列怎么找
创建SpringBoot和RabbitMQ的整合项目
首先快速创建一个maven项目
如下图:
引入SpringBoot整合rabbitMQ的依赖
如下图:
这里要SpringBoot和RabbitMQ整合的依赖对应的就是spring-boot-starter-amqp,那么amqp是什么意思呢?是Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,是面向消息的中间件设计。比如RabbitMQ消息中间件使用的就是这个协议。
因为我们要启动服务,因此需要有tomcat服务器,因此这里还要引入spring-boot-starter-web模块依赖,因为SpringBoot自带的tomcat服务器在web模块里面。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>rabbitMQ</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>rabbitMQ</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.7</version>
</parent>
<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>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
在src/main目录下创建resources目录并引入配置文件
如下图:
写消息发送者MessageSender
如下图:
/**
* @author xuan
* @create 2024/4/25
*/
@Component
public class MessageSender {
@Autowired
private AmqpTemplate rabbitTemplate;
public void sendMessage(String exchange, String routingKey, Object message) {
rabbitTemplate.convertAndSend(exchange, routingKey, message);
}
}
写消息接收者MessageReceiver
如下图:
/**
* @author xuan
* @create 2024/4/25
*/
@Component
public class MessageReceiver {
@RabbitListener(queues = "test.queue")
public void handleMessage(Object message) {
System.out.println("Received message: " + message);
}
}
写RabbitMQConfig配置类
如下图:
/**
* @author xuan
* @create 2024/4/25
*/
@Configuration
public class RabbitMQConfig {
@Bean
public DirectExchange testExchange() {
return new DirectExchange("test.exchange");
}
@Bean
public Queue testQueue() {
return new Queue("test.queue");
}
@Bean
public Binding testBinding() {
return BindingBuilder.bind(testQueue()).to(testExchange()).with("test.routingKey");
}
}
写SpringBoot启动主类
如下图:
/**
* @author xuan
* @create 2024/4/25
*/
@SpringBootApplication
public class Application implements CommandLineRunner {
@Autowired
private MessageSender messageSender;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... args) throws Exception {
messageSender.sendMessage("test.exchange", "test.routingKey", "Hello, RabbitMQ!");
}
}
CommandLineRunner接口的作用
从上面的SpringBoot启动类可以看到,它实现了CommandLineRunner接口,实现了这个接口中的抽象方法run,那么CommandLineRunner接口又什么作用呢?它主要是用在SpringBoot的启动主类上的,主要作用是在SpringBoot应用程序启动之后执行一些任务,比如:
- 数据初始化:加载初始数据到数据库或其他存储系统中。
- 发送通知:向用户或系统发送启动通知,例如通过邮件或消息队列。
- 执行检查:进行应用程序启动前的检查,如数据库连接检查、文件系统检查等。
比如我们上面的主类在成功启动SpringBoot的应用程序之后 就会给RabbitMQ消息队列发送一个消息。
启动程序 查看效果
启动主类之后 控制台输出如下图:
这里我们主要看消息体Body的内容,可以发现是Hello RabbitMQ。后面是消息的一些属性 类似如我们的http协议中的request请求头的信息,包括消息的内容类型了,消息的内容编码了,消息的长度了等信息。
可以发现我们这里测试成功了。
注意要点
15672和5672的区别
RabbitMQ前端管理界面使用的端口号是15672,比如我们启动rabbitmq之后,在浏览器中输入127.0.0.1:15672可以进入rabbitmq的前端页面管理器中进行相关操作,如下图:
但是后端服务器的rabbitmq在电脑上启动的端口号是5672,如下图:
这两个端口号特别容易搞错,千万要注意,如果配置文件里的端口号写15672,那么我们的idea里面的java程序就连接不上我们本地已经启动的rabbitmq服务器了。
消息发送的队列怎么找
通过RabbitMQ中的交换机Exchange,和路由RouteingKey可以唯一的定位到一个消息队列Queue,如下图:
因此我们代码里面发送者发送消息的时候,一定要指定使用的交换机和使用的路由,但不用指定使用的队列,因为有交换机和路由之后就会自动的映射到使用的队列了,看下代码如下图:
但是我们需要通过一个配置类配置一下 需要告诉java程序,如下图:
然后接收者接收消息的时候 可以直接指定test.queue队列,就可以自动的去这个队列中取出消息了。不用写交换机和路由的具体信息。下面看下接收者的处理 如下图:
但是我觉得RabbitMQ应该是会有线程安全问题的,比如说因为目前看来同一个队列 两个不同的线程都是可以访问的,那这样的话有共享资源问题 就肯定会出现线程安全问题。