头部模式是根据头部信息来决定的,在发送的消息中是可以携带一些头部信息的(类似于HTTP),可以根据这些头部信息来决定路由到哪一个消息队列中。
- 定义配置类。
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.ExchangeBuilder;
import org.springframework.amqp.core.HeadersExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* RabbitMQ配置类
*/
@Configuration
public class RabbitMqConfig {
/**
* 定义交换机,可以很多个
* @return 交换机对象
*/
@Bean
public HeadersExchange headersExchange(){
return ExchangeBuilder.headersExchange("amq.headers").build();
}
/**
* 定义消息队列
* @return 消息队列对象
*/
@Bean
public Queue headersQueue(){
return new Queue("headersQueue");
}
/**
* 定义绑定关系
* @return 绑定关系
*/
@Bean
public Binding binding(@Qualifier("headersExchange") HeadersExchange exchange,
@Qualifier("headersQueue") Queue queue){
// 将定义的交换机和队列进行绑定
return BindingBuilder
// 绑定队列
.bind(queue)
// 到交换机
.to(exchange)
// .whereAny("a", "b").exist(); // 这个是只要存在任意一个指定的头部Key就行
// .whereAny(Collections.singletonMap("a", "b")).match(); // 传入Map也行,批量指定键值对
// .whereAll("a", "b").exist(); // 这个是必须存在所有指定的的头部Key
// .whereAll(Collections.singletonMap("a", "b")).match(); // 传入Map也行,批量指定键值对
.where("test").matches("hello"); // 比如我们现在需要消息的头部信息中包含test,并且值为hello才能转发给我们的消息队列
}
}
- 定义消费者。
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* 头部监听器
*/
@Component
public class HeadersListener {
/**
* 监听头部队列消息
*/
@RabbitListener(queuesToDeclare = {@Queue("headersQueue")})
public void receiver(String message) {
System.out.println("头部队列接收到消息:" + message);
}
}
- 定义生产者。
import org.junit.jupiter.api.Test;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class RabbitMqSpringBootTests {
/**
* RabbitTemplate封装了大量的RabbitMQ操作,已经由Starter提供,因此直接注入使用即可
*/
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* 生产者
*/
@Test
void producer() {
Message message = MessageBuilder.withBody("Hello World".getBytes()).setHeader("test","hello").build();
rabbitTemplate.convertAndSend("amq.headers", "", message);
}
}
-
启动生产者发送消息。
可以看到,通过头部的匹配,队列成功接收到了消息。
- 环境
- JDK 17.0.6
- Maven 3.6.3
- SpringBoot 3.0.4
- spring-boot-starter-amqp 3.0.4
- 参考