Google Guava EventBus用于事件编程
EventBus類別
EventBus非常靈活,可以用作單例,或者應(yīng)用程序可以具有多個(gè)實(shí)例以適應(yīng)在不同上下文中傳輸事件。 EventBus將按順序分派所有事件,因此,保持事件處理方法的輕量化很重要。 如果需要在事件處理程序中進(jìn)行更重的處理,則可以使用EventBus的另一種形式,即AsyncEventBus。 AsyncEventBus在功能上是相同的,但是采用ExecutorService作為構(gòu)造函數(shù)參數(shù)來允許事件的異步調(diào)度。
訂閱活動(dòng)
對(duì)象通過以下步驟預(yù)訂事件:
這是一個(gè)簡短的示例,為清楚起見省略了詳細(xì)信息:
public class PurchaseSubscriber {@Subscribepublic void handlePurchaseEvent(PurchaseEvent event) {.....}.....EventBus eventBus = new EventBus();PurchaseSubscriber purchaseSubscriber = new PurchaseSubscriber();eventBus.register(purchaseSubscriber);還有一個(gè)可以與@Subscribe結(jié)合使用的注釋,即@AllowConcurrentEvents。 @AllowConcurrentEvents將處理程序方法標(biāo)記為線程安全的,因此EventBus(很可能是AsyncEventBus)可以潛在地從同時(shí)線程調(diào)用事件處理程序。 我在單元測(cè)試中發(fā)現(xiàn)的一件有趣的事情是,如果處理程序方法沒有@AllowConcurrentEvents批注,則即使使用AsyncEventBus,它也會(huì)按順序調(diào)用事件的處理程序。 重要的是要注意,@ AllowConcurrentEvents不會(huì)將方法標(biāo)記為事件處理程序,@ Subscribe批注仍需要存在。 最后,事件處理方法必須具有一個(gè)且只有一個(gè)參數(shù),否則當(dāng)您在EventBus中注冊(cè)對(duì)象時(shí),將拋出IllegalArgumentException。
發(fā)布事件
同樣,使用EventBus發(fā)布事件也很簡單。 在您要發(fā)送事件通知的代碼部分中,調(diào)用EventBus.post,將為該事件對(duì)象注冊(cè)的所有訂閱者進(jìn)行通知。
public void handleTransaction(){purchaseService.purchase(item,amount);eventBus.post(new CashPurchaseEvent(item,amount));....}盡管這很明顯,但是訂閱類和發(fā)布類共享同一EventBus實(shí)例很重要,并且使用Guice或Spring幫助管理依賴項(xiàng)是有意義的。
有關(guān)事件處理程序的更多信息
EventBus的一項(xiàng)非常強(qiáng)大的功能是,您可以根據(jù)需要使處理程序正常運(yùn)行或細(xì)化。 EventBus將為已發(fā)布事件對(duì)象的所有子類型和已實(shí)現(xiàn)的接口調(diào)用注冊(cè)的訂戶。 例如,要處理所有事件,可以創(chuàng)建一個(gè)帶有Object類型參數(shù)的事件處理程序。 要僅處理單個(gè)事件,請(qǐng)創(chuàng)建一個(gè)特定于類型的處理程序。 為了幫助說明,請(qǐng)考慮以下簡單事件層次結(jié)構(gòu):
public abstract class PurchaseEvent {String item;public PurchaseEvent(String item){this.item = item;} }public class CashPurchaseEvent extends PurchaseEvent {int amount;public CashPurchaseEvent(String item, int amount){super(item);this.amount = amount;} }public class CreditPurchaseEvent extends PurchaseEvent {int amount;String cardNumber;public CreditPurchaseEvent(String item,int amount, String cardNumber){super(item);this.amount = amount;this.cardNumber = cardNumber;} }以下是相應(yīng)的事件處理類:
//Would only be notified of Cash purchase eventspublic class CashPurchaseSubscriber {@Subscribepublic void handleCashPurchase(CashPurchaseEvent event){... }}//Would only be notified of credit purchasespublic class CreditPurchaseSubscriber {@Subscribepublic void handleCreditPurchase(CreditPurchaseEvent event) {....} } //Notified of any purchase eventpublic class PurchaseSubscriber {@Subscribepublic void handlePurchaseEvent(PurchaseEvent event) {.....} }如果需要捕獲各種各樣的事件類型,則替代方法是在一個(gè)類中具有多個(gè)事件處理方法。 擁有多個(gè)處理程序可能是一個(gè)更好的解決方案,因?yàn)槟槐貙?duì)事件對(duì)象參數(shù)進(jìn)行任何“ instanceof”檢查。 這是我的單元測(cè)試中的一個(gè)簡單示例:
public class MultiHandlerSubscriber {List<CashPurchaseEvent> cashEvents = new ArrayList<ashPurchaseEvent>();List<CreditPurchaseEvent> creditEvents = new ArrayList<CreditPurchaseEvent>();List<SimpleEvent> simpleEvents = new ArrayList<SimpleEvent>();public MultiHandlerSubscriber(EventBus eventBus){eventBus.register(this);}@Subscribepublic void handleCashEvents(CashPurchaseEvent event){cashEvents.add(event);}@Subscribepublic void handleCreditEvents(CreditPurchaseEvent event){creditEvents.add(event);}@Subscribepublic void handleSimpleEvents(SimpleEvent event){simpleEvents.add(event);} ....
測(cè)試中
由于事件處理程序只是普通方法,因此可以通過在測(cè)試用例中實(shí)例化一個(gè)EventBus或通過傳遞適當(dāng)?shù)氖录?duì)象來模擬EventBus來輕松對(duì)其進(jìn)行測(cè)試。 當(dāng)使用EventBus時(shí),我發(fā)現(xiàn)很容易:
- 忘記在EventBus中注冊(cè)訂閱對(duì)象
- 忽略添加@Subscribe批注。
如果似乎未調(diào)用事件處理程序,請(qǐng)首先檢查這兩個(gè)錯(cuò)誤。
一種有用的調(diào)試技術(shù)是訂閱DeadEvent類。 EventBus將在DeadEvent實(shí)例中包裝任何沒有處理程序的已發(fā)布事件。 DeadEvent提供了getEvent方法,該方法返回原始事件對(duì)象。
結(jié)論
Guava EventBus類為標(biāo)準(zhǔn)Java事件處理機(jī)制提供了一種有吸引力且有用的替代方法。 希望讀者會(huì)發(fā)現(xiàn)EventBus像我一樣有用。 一如既往地歡迎提出意見和建議。
資源資源
- EventBus API
- 番石榴API
- 樣例代碼
- 活動(dòng)合作
參考:來自我們的JCG合作伙伴 Bill Bejeck的Google Guava EventBus進(jìn)行事件編程,來自Random Thoughts On Coding博客。
翻譯自: https://www.javacodegeeks.com/2012/11/google-guava-eventbus-for-event-programming.html
總結(jié)
以上是生活随笔為你收集整理的Google Guava EventBus用于事件编程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深圳市备案价查询(深圳市备案)
- 下一篇: Linux忘记密码了怎么办(linux忘