Spring AMQP基本API
Spring AMQP基本API
1. RabbitTemplate【发接消息】
RabbitTemplate
是 Spring AMQP 的核心 API,用于发送和接收消息。它提供了多种方法来发送消息到指定的交换机和路由键。
- 发送消息:将消息发送到指定的交换机和路由键。
- 接收消息:从指定的队列中接收消息。
- 消息转换:支持消息序列化和反序列化,可以将Java对象转换为消息或从消息中恢复Java对象。
java@Autowired
private RabbitTemplate rabbitTemplate;
// 发送消息
// 1 交换机名称、2路由routing_key,3、发送的内容
rabbitTemplate.convertAndSend("exchangeName", "routingKey", "message");
// 接收消息
String message = (String) rabbitTemplate.receiveAndConvert("queueName");
//发送一个延迟消息(30分钟)
MessagePostProcessor messagePostProcessor = message -> {
message.getMessageProperties().setDelay(60*30 * 1000);//30分钟
return message;
};
rabbitTemplate.convertAndSend("exchangeName", "routingKey", "message",messagePostProcessor);
// 发送延迟消息(10秒)
@Test
public void testSendDelayMessage1() {
rabbitTemplate.convertAndSend(
EXCHANGE_DELAY,
ROUTING_KEY_DELAY,
"测试基于插件的延迟消息 [" + new SimpleDateFormat("hh:mm:ss").format(new Date()) + "]",
messageProcessor -> {
// 设置延迟时间:以毫秒为单位
messageProcessor.getMessageProperties().setHeader("x-delay", "10000");
return messageProcessor;
});
}
RabbitService
RabbitService
并不是Spring AMQP提供的标准组件,但它可能是一个自定义类,用于封装与RabbitMQ相关的业务逻辑。这个服务可能会使用RabbitTemplate
进行实际的消息发送和接收操作,通过提供更高层次的API来简化与RabbitMQ的交互。
java@Service
public class RabbitService {
@Autowired
private RabbitTemplate rabbitTemplate;
public void publishMessage(String exchange, String routingKey, String message) {
rabbitTemplate.convertAndSend(exchange, routingKey, message);
}
public String consumeMessage(String queueName) {
return (String) rabbitTemplate.receiveAndConvert(queueName);
}
}
2. MessageListener【处理信息】
MessageListener
接口用于定义如何处理接收到的消息。它通常与 SimpleMessageListenerContainer
或 ConcurrentMessageListenerContainer
一起使用。
java@Component
public class MyMessageListener implements MessageListener {
@Override
public void onMessage(Message message) {
// 处理接收到的消息
String msgBody = new String(message.getBody());
System.out.println("Received message: " + msgBody);
}
}
3. RabbitMessageConverter【转换消息】
用于在发送和接收消息时进行消息的转换。常见的转换器包括 MappingJackson2MessageConverter
(用于 JSON)和 SimpleMessageConverter
(用于文本)。
java@Bean
public RabbitMessagingTemplate rabbitMessagingTemplate(ConnectionFactory connectionFactory) {
RabbitMessagingTemplate template = new RabbitMessagingTemplate(connectionFactory);
template.setMessageConverter(new MappingJackson2MessageConverter());
return template;
}
4. RabbitAdmin【管理队列、交换机...】
RabbitAdmin
是一个自动化管理的组件,用于创建和删除队列、交换机和绑定关系等。
java@Autowired
private RabbitAdmin rabbitAdmin;
// 创建队列
rabbitAdmin.declareQueue(new Queue("myQueue"));
// 创建交换机
rabbitAdmin.declareExchange(new DirectExchange("myExchange"));
// 创建绑定
rabbitAdmin.declareBinding(BindingBuilder.bind(new Queue("myQueue")).to(new DirectExchange("myExchange")).with("routingKey"));
5. Queue, Exchange, Binding
在 Spring AMQP 中,队列、交换机和绑定是基本组件,分别用于消息存储、消息路由和连接队列与交换机。
//创建队列
@Bean
public Queue myQueue() {
return new Queue("myQueue");
}
//创建交换机
@Bean
public DirectExchange myExchange() {
return new DirectExchange("myExchange");
}
//交换机与队列进行绑定
@Bean
public Binding myBinding() {
return BindingBuilder.bind(myQueue()).to(myExchange()).with("routingKey");
}
我们可以自己创建队列和交换机,不过SpringAMQP还提供了ExchangeBuilder来简化这个过程:
fanout示例
@Configuration
public class FanoutConfig {
/**
* 声明交换机
* @return Fanout类型交换机
*/
@Bean
public FanoutExchange fanoutExchange(){
return new FanoutExchange("hmall.fanout");
}
/**
* 第1个队列
*/
@Bean
public Queue fanoutQueue1(){
return new Queue("fanout.queue1");
}
/**
* 绑定队列和交换机
*/
@Bean
public Binding bindingQueue1(Queue fanoutQueue1, FanoutExchange fanoutExchange){
return BindingBuilder.bind(fanoutQueue1).to(fanoutExchange);
}
/**
* 第2个队列
*/
@Bean
public Queue fanoutQueue2(){
return new Queue("fanout.queue2");
}
/**
* 绑定队列和交换机
*/
@Bean
public Binding bindingQueue2(Queue fanoutQueue2, FanoutExchange fanoutExchange){
return BindingBuilder.bind(fanoutQueue2).to(fanoutExchange);
}
}
direct示例
@Configuration
public class DirectConfig {
/**
* 声明交换机
* @return Direct类型交换机
*/
@Bean
public DirectExchange directExchange(){
return ExchangeBuilder.directExchange("hmall.direct").build();
}
/**
* 第1个队列
*/
@Bean
public Queue directQueue1(){
return new Queue("direct.queue1");
}
/**
* 绑定队列和交换机
*/
@Bean
public Binding bindingQueue1WithRed(Queue directQueue1, DirectExchange directExchange){
return BindingBuilder.bind(directQueue1).to(directExchange).with("red");
}
/**
* 绑定队列和交换机
*/
@Bean
public Binding bindingQueue1WithBlue(Queue directQueue1, DirectExchange directExchange){
return BindingBuilder.bind(directQueue1).to(directExchange).with("blue");
}
/**
* 第2个队列
*/
@Bean
public Queue directQueue2(){
return new Queue("direct.queue2");
}
/**
* 绑定队列和交换机
*/
@Bean
public Binding bindingQueue2WithRed(Queue directQueue2, DirectExchange directExchange){
return BindingBuilder.bind(directQueue2).to(directExchange).with("red");
}
/**
* 绑定队列和交换机
*/
@Bean
public Binding bindingQueue2WithYellow(Queue directQueue2, DirectExchange directExchange){
return BindingBuilder.bind(directQueue2).to(directExchange).with("yellow");
}
}
基于注解声明创建队列和交换机
基于@Bean的方式声明队列和交换机比较麻烦,Spring还提供了基于注解方式来声明。基于@RabbitListener注解
Direct模式
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "direct.queue1"),
exchange = @Exchange(name = "hmall.direct", type = ExchangeTypes.DIRECT),
key = {"red", "blue"}
))
public void listenDirectQueue1(String msg){
System.out.println("消费者1接收到direct.queue1的消息:【" + msg + "】");
}
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "direct.queue2"),
exchange = @Exchange(name = "hmall.direct", type = ExchangeTypes.DIRECT),
key = {"red", "yellow"}
))
public void listenDirectQueue2(String msg){
System.out.println("消费者2接收到direct.queue2的消息:【" + msg + "】");
}
Topic模式
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "topic.queue1"),
exchange = @Exchange(name = "hmall.topic", type = ExchangeTypes.TOPIC),
key = "china.#"
))
public void listenTopicQueue1(String msg){
System.out.println("消费者1接收到topic.queue1的消息:【" + msg + "】");
}
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "topic.queue2"),
exchange = @Exchange(name = "hmall.topic", type = ExchangeTypes.TOPIC),
key = "#.news"
))
public void listenTopicQueue2(String msg){
System.out.println("消费者2接收到topic.queue2的消息:【" + msg + "】");
}
创建死信交换机和队列
@Configuration
public class DeadLetterMqConfig {
// 声明一些变量
public static final String exchange_dead = "exchange.dead";
public static final String routing_dead_1 = "routing.dead.1";
public static final String routing_dead_2 = "routing.dead.2";
public static final String queue_dead_1 = "queue.dead.1";
public static final String queue_dead_2 = "queue.dead.2";
// 定义交换机
@Bean
public DirectExchange exchange() {
return new DirectExchange(exchange_dead, true, false, null);
}
@Bean
public Queue queue1() {
// 设置如果队列一 出现问题,则通过参数转到exchange_dead,routing_dead_2 上!
HashMap<String, Object> map = new HashMap<>();
// 参数绑定 此处的key 固定值,不能随意写
map.put("x-dead-letter-exchange", exchange_dead);
map.put("x-dead-letter-routing-key", routing_dead_2);
// 设置延迟时间
map.put("x-message-ttl", 10 * 1000);
// 队列名称,是否持久化,是否独享、排外的【true:只可以在本次连接中访问】,是否自动删除,队列的其他属性参数
return new Queue(queue_dead_1, true, false, false, map);
}
@Bean
public Binding binding() {
// 将队列一 通过routing_dead_1 key 绑定到exchange_dead 交换机上
return BindingBuilder.bind(queue1()).to(exchange()).with(routing_dead_1);
}
// 这个队列二就是一个普通队列
@Bean
public Queue queue2() {
return new Queue(queue_dead_2, true, false, false, null);
}
// 设置队列二的绑定规则
@Bean
public Binding binding2() {
// 将队列二通过routing_dead_2 key 绑定到exchange_dead交换机上!
return BindingBuilder.bind(queue2()).to(exchange()).with(routing_dead_2);
}
}
创建延迟队列
注意:需要安装延迟插件
https://github.com/rabbitmq/rabbitmq-delayed-message-exchange
@Configuration
public class CancelOrderMqConfig {
@Bean
public Queue cancelQueue() {
// 第一个参数是创建的queue的名字,第二个参数是是否支持持久化
return new Queue(queue_name, true);
}
//创建MQ的交换机
@Bean
public CustomExchange cancelExchange() {
Map<String, Object> args = new HashMap<String, Object>();
//设置配置参数
args.put("x-delayed-type", "direct");
//第一个参数是交换机名称、第二个参数是交换机类型
//第三个参数是是否持久化、第四个参数是否自动删除
//第五个参数是交换机的其他属性参数
return new CustomExchange(exchange_name, "x-delayed-message", true, false, args);
}
@Bean
public Binding bindingCancel() {
//创建的队列,去创建的交换机进行绑定。通过路由的routing_key,noargs() 表示该绑定不带任何额外的参数
return BindingBuilder.bind(cancelQueue()).to(cancelExchange()).with(routing_key).noargs();
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报