Spring中@RabbitHandler和@RabbitListener的區(qū)別詳析
@RabbitHandler 和 @RabbitListener 是Spring AMQP(特別是針對RabbitMQ)中常用的兩個注解,它們在消息處理中扮演著不同的角色。
@RabbitListener
定義:
@RabbitListener注解用于標記一個方法,使其成為消息隊列的監(jiān)聽器,即這個方法負責接收來自RabbitMQ的消息。使用場景:當你想讓某個服務類中的方法直接監(jiān)聽某個RabbitMQ隊列時,你會在該方法上使用
@RabbitListener。功能:
- 它可以指定監(jiān)聽的隊列、交換機和路由鍵。
- 支持異步處理,可以處理發(fā)送到指定隊列的消息。
- 可以與Spring的
@Transactional注解結合使用,以確保消息處理的事務性。
@RabbitHandler
定義:
@RabbitHandler注解用于標記一個方法,作為特定類型的消息的處理器。使用場景:在一個類中可能有多個不同的方法處理不同類型的消息。這時,你可以在這個類上使用
@RabbitListener,然后在每個處理方法上使用@RabbitHandler,以便根據消息類型調用適當的方法。功能:
- 主要用于方法級別的多態(tài),即在同一個類中根據消息的不同類型來調用不同的處理方法。
- 允許你在同一個監(jiān)聽器類中定義多個處理不同類型消息的方法。
結合使用
- 通常,
@RabbitListener用于類級別或方法級別,定義消息的入口點,即指定哪個隊列的消息會被監(jiān)聽。 @RabbitHandler則用于在同一類中的不同方法上,根據接收到的消息類型調用相應的方法。
示例
@Component
public class MyMessageListener {
@RabbitListener(queues = "myQueue")
public void process(String data) {
// 處理字符串類型的消息
}
@RabbitListener(queues = "myQueue")
@RabbitHandler
public void process(MyCustomObject object) {
// 處理 MyCustomObject 類型的消息
}
}
在這個示例中,@RabbitListener 用于指定監(jiān)聽的隊列,而 @RabbitHandler 用于區(qū)分不同類型的消息應由哪個方法處理。這種結構使得在同一個監(jiān)聽器類中可以方便地處理多種類型的消息。
更詳細的例子來闡明 @RabbitListener 和 @RabbitHandler 在實際使用中的差異和結合方式。
示例 1:基本的 @RabbitListener 使用
假設有一個場景,你需要監(jiān)聽一個名為 ordersQueue 的RabbitMQ隊列,并對收到的訂單消息進行處理。
@Component
public class OrderService {
@RabbitListener(queues = "ordersQueue")
public void receiveOrder(String orderJson) {
// 解析訂單JSON數據
Order order = parseOrder(orderJson);
// 處理訂單
processOrder(order);
}
// ...其他方法,如parseOrder和processOrder
}
在這個例子中,@RabbitListener 直接應用于方法 receiveOrder,這意味著這個方法將監(jiān)聽 ordersQueue 隊列,并處理所有接收到的消息。
示例 2:結合使用 @RabbitListener 和 @RabbitHandler
考慮一個稍微復雜的場景,其中一個服務需要處理兩種類型的消息:文本消息和JSON格式的訂單消息。
@Component
@RabbitListener(queues = "mixedMessagesQueue")
public class MixedMessageService {
@RabbitHandler
public void processTextMessage(String text) {
// 處理文本消息
System.out.println("Received text message: " + text);
}
@RabbitHandler
public void processOrderMessage(Order order) {
// 處理訂單對象
System.out.println("Received order: " + order);
}
// ...其他可能的方法
}
在這個例子中,@RabbitListener 注解應用于類級別,意味著這個類中的所有方法都會監(jiān)聽 mixedMessagesQueue 隊列。@RabbitHandler 則用于區(qū)分不同的處理方法:processTextMessage 用于處理文本消息,而 processOrderMessage 用于處理訂單對象。Spring會根據消息的類型自動選擇合適的方法。
示例 3:使用 @RabbitListener 的多方法監(jiān)聽
在某些情況下,你可能希望在同一個類中,不同的方法監(jiān)聽不同的隊列。
@Component
public class MultiQueueListener {
@RabbitListener(queues = "textQueue")
public void processTextMessage(String text) {
// 處理來自textQueue的文本消息
}
@RabbitListener(queues = "ordersQueue")
public void processOrder(Order order) {
// 處理來自ordersQueue的訂單消息
}
}
這個例子展示了在同一個類中,不同的方法可以監(jiān)聽不同的隊列。processTextMessage 監(jiān)聽 textQueue 隊列,而 processOrder 監(jiān)聽 ordersQueue 隊列。
這些例子展示了 @RabbitListener 和 @RabbitHandler 在不同場景下的應用方式,包括單獨使用 @RabbitListener、將 @RabbitListener 與 @RabbitHandler 結合使用以及在同一個類中使用多個 @RabbitListener 注解來監(jiān)聽不同的隊列。
附:@RabbitListener或@RabbitHandler使用出現(xiàn)死循環(huán)
異常1問題:為什么會找不到消費實現(xiàn)?
@RabbitListener 或 @RabbitHandler 配置出錯
很大原因是取決于content_type 的配置和 方法的形參。
如果通過客戶端放入隊列中有個content_type為空的的消息,@RabbitListener只有形參為String 的Handler,是無法對應上消費實現(xiàn)的。
@RabbitHandler 沒有使用可選參數isDefault
消費者找不到任何一個消費實現(xiàn),就回去找isDefault = true 的 handler,類似一個兜底策略。
異常1問題:處理思路
使用Message 作為方法形參
盡量將@RabbitListener 放在類上, 使用@RabbitHandler(isDefault = true) 做兜底策略
異常1分析 :死循環(huán)分析
這是一種應用級別的死循環(huán),消息找不到消費實現(xiàn),一直重試直到找到消費實現(xiàn)。這種死循環(huán)原因是配置失誤,要在源頭避免,測試階段就要消滅?!菊业较@種死循環(huán)的方法再來填坑】。另外一種必須處理的死循環(huán)是已經找到消費實現(xiàn),但是在消費的過程中造成死循環(huán),見異常2:
【異常2】:消費過程中拋出未捕獲Exception
通常是業(yè)務邏輯導致的異常如NullPointerException,無腦的做法是try-catch,處理不當依舊會造成死循環(huán)。
異常2問題:try-catch后仍然會死循環(huán)
總結
到此這篇關于Spring中@RabbitHandler和@RabbitListener區(qū)別的文章就介紹到這了,更多相關@RabbitHandler和@RabbitListener區(qū)別內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Sublime Text 打開Java文檔中文亂碼的解決方案
這篇文章主要介紹了Sublime Text 中文亂碼的解決方案,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下2020-12-12
java下載指定文件并返回給前端返回流文件的實現(xiàn)步驟
在Java中我們可以根據文件地址返回一個文件流,以便對文件進行讀取、寫入等操作,下面這篇文章主要給大家介紹了關于java下載指定文件并返回給前端返回流文件的實現(xiàn)步驟,需要的朋友可以參考下2024-03-03
packages思維及使用Java添加Android平臺特定實現(xiàn)
這篇文章主要為大家介紹了packages思維及使用Java添加Android平臺特定實現(xiàn)在Flutter框架里的體現(xiàn)和運用詳解,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12

