先說下這個參數的作用:
/**
* Mandatory為true時,消息通過交換器無法匹配到隊列會返回給生產者
* 為false時,匹配不到會直接被丟棄
*/
在一些特定場景下還是有用處的!
接下來說一下綁定隊列與交換器,需要在配置類或者xml中提前配置好
尤其是queue,如果同時寫了消費者,必須先配置好bean,即mq中隊列必須存在,不然會報錯
//創建消息隊列
@Bean
public Queue testQueue(){
//boolean表示消息是否持久化
return new Queue("testQueue",true);
}
//創建交換器
@Bean
public DirectExchange exchange(){
//boolean表示消息是否持久化
return new DirectExchange("exchange");
}
//通過指定key綁定隊列與交換器
@Bean
Binding bindingExchangeMessages(@Qualifier("testQueue") Queue queue, DirectExchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("routeKey");
}
綁定好之后就可以測試這個參數了,使用我們指定的交換器和key!
程序啟動之后會自動創建,這里如果需要捕獲匹配失敗的消息需要添加一個監聽器
測試:當參數設置為true時,寫個錯誤的key:

@Override
public void sendTest() {
/**
* Mandatory為true時,消息通過交換器無法匹配到隊列會返回給生產者
* 為false時,匹配不到會直接被丟棄
*/
rabbitTemplate.setMandatory(true);
//添加監聽器獲取返送失敗的消息
rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
@Override
public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
System.out.println("replyCode:"+replyCode);
System.out.println("replyText:"+replyText);
System.out.println("匹配隊列失敗,返回消息:" + message.toString());
}
});
// 向指定交換器發送消息,需要key
rabbitTemplate.convertAndSend("exchange","route","測試消息內容");
}
由於key不對,匹配隊列失敗,參數為true,所以消息會返回給生產者:

如果寫上正確key,則正常發送接受,如果
setMandatory
設置為false,則匹配不到的消息直接被丟棄!
還可以直接使用備份交換器更方便!
只要配置即可,注意,這里如果之前配置錯了,要么重新刪除交換器,要么解綁,否則不起作用
配置:
//備份交互器
@Bean
public FanoutExchange unrouteExchange(){
return new FanoutExchange("unrouteExchange",true,false);
}
//創建備份交互器與備份交互器隊列
@Bean
public Queue unrouteQueue(){
return new Queue("unrouteQueue",true);
}
//綁定備份交互器與備份隊列,不需要指定key
@Bean
Binding bindingUnRouteExchangeMessages() {
return BindingBuilder.bind(unrouteQueue()).to(unrouteExchange());
}
//創建消息隊列
@Bean
public Queue testQueue(){
//boolean表示消息是否持久化
return new Queue("testQueue",true);
}
//創建交換器
@Bean
public DirectExchange exchange(){
// 指定此交換器的備份交互器,存儲沒有被路由的消息
Map<String, Object> args = new HashMap<>();
args.put("alternate-exchange", "unrouteExchange");
return new DirectExchange("exchange",true,false,args);
}
//通過指定key綁定隊列與交換器
@Bean
Binding bindingExchangeMessages() {
return BindingBuilder.bind(testQueue()).to(exchange()).with("routeKey");
}
此時再測試會發現消息進入了備份隊列:

這里有個坑點,如果配置錯了,即交換器不存在或者交互器沒有綁定隊列,不會報錯,消息會直接丟失
我之前這里就是配置交互器名稱寫成了隊列的名稱,所以消息一直丟失,搞了大半天!!!!一定要認真!
