导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
添加配置
spring:
rabbitmq:
host: localhost
port: 5672
rabbitmq直连模式(direct)配置项:
package com.example.demo_mq.service.impl.rabbitmq.direct.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 RabbitDirectConfig {
@Bean
public Queue directQueue(){
//返回一个名为direct_queue的队列
return new Queue("direct_queue");
}
@Bean
public DirectExchange directExchange(){
//返回一个名为directExchange的交换机
return new DirectExchange("directExchange");
}
@Bean
public Binding bindingDirect(){
//将队列和交换机绑定 并指定routingkey为direct
return BindingBuilder.bind(directQueue()).to(directExchange()).with("direct");
}
}
Service层接口和实现类
接口:IMsgService.java
package com.example.demo_mq.service;
public interface IMsgService {
void sendMsg(String id);
String doMsg();
}
接口:IOrderService.java
package com.example.demo_mq.service;
public interface IOrderService {
void order(String id);
}
实现类:OrderServiceImpl
package com.example.demo_mq.service.impl;
import com.example.demo_mq.service.IMsgService;
import com.example.demo_mq.service.IOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class OrderServiceImpl implements IOrderService {
@Autowired
private IMsgService msgService;
@Override
public void order(String id) {
msgService.sendMsg(id);
}
}
直连模式-生产者(发送者)
package com.example.demo_mq.service.impl.rabbitmq.direct;
import com.example.demo_mq.service.IMsgService;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class MsgServiceRabbitDirectImpl implements IMsgService {
@Autowired
private AmqpTemplate amqpTemplate;
@Override
public void sendMsg(String id) {
System.out.println("待发送的消息已纳入处理队列(rabbitmq direct) id:" + id);
amqpTemplate.convertAndSend("directExchange","direct",id);
}
@Override
public String doMsg() {
return null;
}
}
直连模式-消费者(接收者)
若定义多个消费者监听同一个消息队列,则会将消息轮流发送,如第一次发送接受者1接收到信息,第二次发送接收者2接收到信息。
package com.example.demo_mq.service.impl.rabbitmq.direct.listener;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class MsgListener {
@RabbitListener(queues = "direct_queue") //指定监听队列
public void recive(String id){
System.out.println("已完成短信发送业务(rabbitmq direct) id:"+id);
}
}
controller层
OrderControler.java
package com.example.demo_mq.controller;
import com.example.demo_mq.service.IOrderService;
import com.example.demo_mq.service.impl.OrderServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/orders")
public class OrderController {
@Autowired
IOrderService orderService;
@PostMapping("{id}")
public void order(@PathVariable String id){
orderService.order(id);
}
}
发送post请求
请求http:localhost:8080/orders/1 控制台输出如下:
以上采用直连模式实现发送和接收消息
topic模式配置项
topic 需要更改交换机DirectExchange为TopicExchange,
topic 需要根据routing key的匹配规则来转发到不同的队列,
匹配规则为:
- *可以代替一个单词
- #可以代替>=0个单词。
更改直连模式配置项:
package com.example.demo_mq.service.impl.rabbitmq.topic.config;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitTopicConfig {
@Bean
public Queue topicQueue(){
return new Queue("topic_queue");
}
@Bean
public Queue topicQueue2(){
return new Queue("topic_queue2");
}
@Bean
public TopicExchange topicExchange(){
return new TopicExchange("topicExchange");
}
@Bean
public Binding bindingTopic(){
return BindingBuilder.bind(topicQueue()).to(topicExchange()).with("topic.order.*");
}
@Bean
public Binding bindingTopic2(){
return BindingBuilder.bind(topicQueue2()).to(topicExchange()).with("topic.*.id");
}
}
添加消费者用来监听不同队列的消息
package com.example.demo_mq.service.impl.rabbitmq.topic.listener;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class MsgListener {
@RabbitListener(queues = "topic_queue")
public void recive(String id){
System.out.println("已完成短信发送业务(rabbitmq topic 1) id:"+id);
}
@RabbitListener(queues = "topic_queue2")
public void recive2(String id){
System.out.println("已完成短信发送业务(rabbitmq topic 2) id:"+id);
}
}
修改实现类中的sendMsg()方法
@Override
public void sendMsg(String id) {
System.out.println("待发送的消息已纳入处理队列(rabbitmq topic ) id:" + id);
amqpTemplate.convertAndSend("topicExchange","topic.order.id",id);
}
topic.order.id会匹配topic.* .id和topic.order.* 所以会发送信息到两个消息队列
发送post请求http://localhost:8080/orders/hello控制台输出如下