前文
文章目录
direct 模式
消息生产者
创建 Maven 工程
关于怎么创建 Maven 工程这里就不详细介绍了,创建好的工程如下:
添加 Maven 依赖
<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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
application.properties
# 启动服务端口
server.port=8081
# 服务名称
spring.application.name=test-rabbitmq-producer
# RabbitMQ 配置
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.virtual-host=/
自定义 Exchange(交换机)
新建一个 config 包,在该包下新建一个配置类,如下:
package com.java.rabbitmq.producer.config;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Woo_home
* @create 2020/5/27 14:09
*/
@Configuration
public class RabbitMQConfig {
// 声明交换机
@Bean
public DirectExchange directExchange() {
return new DirectExchange("EmailExchange");
}
}
Controller
package com.java.rabbitmq.producer.controller;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
* @author Woo_home
* @create 2020/5/27 14:30
*/
@RestController
public class AMQPController {
// 注入 RabbitTemplate 模板
@Autowired
public RabbitTemplate rabbitTemplate;
@GetMapping("/direct")
public String sendEmail(@RequestParam Map<String, Object> param) {
// 获取参数
String msg = param.get("msg").toString();
// 发送消息,绑定的交换机名称为 EmailExchange,路由为 EmailRouting
rabbitTemplate.convertAndSend("EmailExchange", "EmailRouting", msg);
return "OK";
}
}
主启动类
package com.java.rabbitmq.producer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ProducerApplication {
public static void main(String[] args) {
SpringApplication.run(ProducerApplication.class, args);
}
}
消息消费者
创建 Maven 工程
跟上面的一样,创建好的 Maven 工程如下:
添加 Maven 依赖
依赖跟上面是一样的,直接复制即可
application.properties
# 启动服务端口
server.port=8082
# 服务名称
spring.application.name=test-rabbitmq-producer
# RabbitMQ 配置
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.virtual-host=/
自定义配置类
package com.java.rabbitmq.consumer.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 Woo_home
* @create 2020/5/27 14:09
*/
@Configuration
public class RabbitMQConfig {
// 声明交换机
@Bean
public DirectExchange emailExchange() {
// 这里的交换机要与生产者的交换机名称一致
return new DirectExchange("EmailExchange");
}
// 声明队列
@Bean
public Queue emailQueue() {
// 队列名称
return new Queue("EmailQueue");
}
// 绑定交换机和队列
@Bean
public Binding bindEmail() {
return BindingBuilder.bind(emailQueue())
// 绑定交换机
.to(emailExchange())
// 和路由
.with("EmailRouting");
}
}
Service
接下来就可以编写业务代码了,其实这个业务代码只是简单接收一下生产者发送的消息即可,代码如下:
package com.java.rabbitmq.consumer.service;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* @author Woo_home
* @create 2020/5/27 14:49
*/
@Component
public class EmailService {
// 监听队列名称为 EmailQueue 的队列
@RabbitListener(queues = "EmailQueue")
public void receive(String msg) {
// 打印消息
System.out.println("收到的消息 " + msg);
}
}
测试
在测试之前可以先把 RabbitMQ 的数据都先清除先,以免混淆,清除 RabbitMQ 数据的命令如下:
rabbitmqctl stop_app
rabbitmqctl reset
rabbitmqctl start_app
启动消息生产者
访问 http://localhost:8081/direct?msg=2222 如果返回 OK,那么就可以了
刷新一下 Exchange 页面
但是点击 Exchange 进去的时候发现还没有绑定任何东西
这是因为我没还没有启动消息消费者,这里启动一下消息消费者
刷新一下 Queue 界面 http://localhost:15672/#/queues,这个时候就有了一个队列
这个时候点击 Connection 选项就会出现两个连接
而且此时的交换机已经绑定了我们的队列
再次刷新 http://localhost:8081/direct?msg=2222 页面时
消费者的控制台就会输出消息
topic (通配符模式)
消息生产者
配置 Bean
package com.java.rabbitmq.producer.config;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Woo_home
* @create 2020/5/28 21:08
*/
@Configuration
public class BlogConfig {
// 声明交换机
@Bean
public TopicExchange blogExchange() {
return new TopicExchange("BlogExchange");
}
}
Controller
package com.java.rabbitmq.producer.controller;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
* @author Woo_home
* @create 2020/5/27 14:30
*/
@RestController
public class AMQPController {
// 注入 RabbitTemplate 模板
@Autowired
public RabbitTemplate rabbitTemplate;
@GetMapping("/direct")
public String sendEmail(@RequestParam Map<String, Object> param) {
// 获取参数
String msg = param.get("msg").toString();
// 发送消息
rabbitTemplate.convertAndSend("EmailExchange", "EmailRouting", msg);
return "OK";
}
@GetMapping("/topic")
public String sendBlog(@RequestParam Map<String, Object> param) {
String msg = param.get("msg").toString();
String routingKey = param.get("key").toString();
rabbitTemplate.convertAndSend("BlogExchange", routingKey, msg);
return "OK";
}
}
主要是增加以下代码
消息消费者
配置 Bean
package com.java.rabbitmq.consumer.config;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Woo_home
* @create 2020/5/28 21:08
*/
@Configuration
public class BlogConfig {
// 声明交换机
@Bean
public TopicExchange blogExchange() {
return new TopicExchange("BlogExchange");
}
// 声明队列名称
@Bean
public Queue blogJavaQueue() {
return new Queue("BlogQueue", true);
}
// 声明队列名称
@Bean
public Queue blogJavaNotQueue() {
return new Queue("BlogDotNetQueue", true);
}
// 声明队列名称
@Bean
public Queue blogAllQueue() {
return new Queue("BlogAllQueue", true);
}
// 绑定队列和交换机
@Bean
public Binding bindingToJavaQueue() {
return BindingBuilder.bind(blogJavaQueue())
.to(blogExchange())
.with("blog.java");
}
// 绑定队列和交换机
@Bean
public Binding bindingToDotNetQueue() {
return BindingBuilder.bind(blogJavaNotQueue())
.to(blogExchange())
.with("blog.doNet");
}
// 绑定队列和交换机
@Bean
public Binding bindingToAllQueue() {
return BindingBuilder.bind(blogAllQueue())
.to(blogExchange())
// 表示只要是 blog 开头的即可
.with("blog.#");
}
}
业务类
package com.java.rabbitmq.consumer.service;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* @author Woo_home
* @create 2020/5/28 21:25
*/
@Component
public class BlogService {
// 监听队列
@RabbitListener(queues = "BlogQueue")
public void receiverJava(String msg) {
System.out.println("收到的 Java 消息是:" + msg);
}
// 监听队列
@RabbitListener(queues = "BlogDotNetQueue")
public void receiverDotNet(String msg) {
System.out.println("收到的 DotNet 消息是:" + msg);
}
// 监听队列
@RabbitListener(queues = "BlogAllQueue")
public void receiverAll(String msg) {
System.out.println("收到的 All 消息是:" + msg);
}
}
测试
访问 http://localhost:15672/#/exchanges ,可以发现,BlogExchange 已经添加进来
声明的队列
绑定的交换机和队列
访问 http://localhost:8081/topic?msg=SpringBoot整合RabbitMQ&key=blog.java
控制台输出(只要是以 .java 结尾或者 .# 都可以输出)
访问 .doNet 结尾的也是可以的
控制台输出:
fanout 模式
生产者
配置 Bean
package com.java.rabbitmq.producer.config;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Woo_home
* @create 2020/5/27 14:09
*/
@Configuration
public class FanoutConfig {
// 声明交换机
@Bean
public FanoutExchange fanoutExchange() {
return new FanoutExchange("FanoutExchange");
}
}
Controller
package com.java.rabbitmq.producer.controller;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
* @author Woo_home
* @create 2020/5/27 14:30
*/
@RestController
public class AMQPController {
// 注入 RabbitTemplate 模板
@Autowired
public RabbitTemplate rabbitTemplate;
@GetMapping("/direct")
public String sendEmail(@RequestParam Map<String, Object> param) {
// 获取参数
String msg = param.get("msg").toString();
// 发送消息
rabbitTemplate.convertAndSend("EmailExchange", "EmailRouting", msg);
return "OK";
}
@GetMapping("/topic")
public String sendBlog(@RequestParam Map<String, Object> param) {
String msg = param.get("msg").toString();
String routingKey = param.get("key").toString();
rabbitTemplate.convertAndSend("BlogExchange", routingKey, msg);
return "OK";
}
@GetMapping("/fanout")
public String sendFanout(@RequestParam Map<String, Object> param) {
String msg = param.get("msg").toString();
rabbitTemplate.convertAndSend("FanoutExchange", null, msg);
return "OK";
}
}
主要新增以下代码
消费者
配置 Bean
package com.java.rabbitmq.consumer.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 Woo_home
* @create 2020/5/27 14:09
*/
@Configuration
public class FanoutConfig {
// 声明交换机
@Bean
public FanoutExchange fanoutExchange() {
return new FanoutExchange("FanoutExchange");
}
// 声明队列
@Bean
public Queue fanoutQueue() {
return new Queue("FanoutQueue");
}
// 声明队列
@Bean
public Queue fanoutQueue2() {
return new Queue("FanoutQueue2");
}
// 绑定交换机和队列
@Bean
public Binding bindFanout() {
return BindingBuilder
.bind(fanoutQueue())
.to(fanoutExchange());
}
// 绑定交换机和队列
@Bean
public Binding bindFanout2() {
return BindingBuilder
.bind(fanoutQueue2())
.to(fanoutExchange());
}
}
业务类
这个类很简单,就打印接收的消息即可
package com.java.rabbitmq.consumer.service;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* @author Woo_home
* @create 2020/5/27 14:49
*/
@Component
public class FanoutService {
@RabbitListener(queues = "FanoutQueue")
public void receive(String msg) {
System.out.println("收到的消息 " + msg);
}
@RabbitListener(queues = "FanoutQueue2")
public void receive2(String msg) {
System.out.println("收到的消息 " + msg);
}
}
测试
启动生产者和消费者服务
声明的队列
声明的交换机
交换机绑定的队列
在浏览器中输入以下地址返回 OK 即可
控制台输出
相关 MQ 文章阅读
ActiveMQ —— Java 连接 ActiveMQ(点对点)
ActiveMQ —— Java 连接 ActiveMQ(发布订阅 Topic)