在任何软件应用程序中都是如此,有些对象需要共享信息才能完成工作。 在Java应用程序中,实现信息共享的一种方法是拥有事件侦听器,其唯一目的是在发生所需事件时采取某些措施。 在大多数情况下,此过程有效,并且最有经验的Java开发人员习惯于编写实现某些事件侦听器接口的必需的匿名内部类。 这篇文章是关于使用Guava的EventBus处理Java事件的另一种方法。 EventBus允许对象订阅发布事件,而无需彼此明确了解。 EventBus并不旨在成为通用的发布/订阅系统,也不支持进程间通信。

EventBus类别

EventBus非常灵活,可以用作单例,或者应用程序可以具有多个实例以适应在不同上下文中传输事件。 EventBus将按顺序分派所有事件,因此,保持事件处理方法的轻量化很重要。 如果需要在事件处理程序中进行更重的处理,则可以使用EventBus的另一种形式,即AsyncEventBus。 AsyncEventBus在功能上是相同的,但是采用ExecutorService作为构造函数参数来允许事件的异步调度。

订阅活动

对象通过以下步骤预订事件:

  1. 定义一个采用所需事件类型的单个参数的公共方法,并在该方法上放置@Subscribe批注。
  2. 通过将对象的实例传递给EventBus.register方法来向EventBus注册。

这是一个简短的示例,为清楚起见省略了详细信息:

public class PurchaseSubscriber {@Subscribepublic void handlePurchaseEvent(PurchaseEvent event) {.....}.....EventBus eventBus = new EventBus();PurchaseSubscriber purchaseSubscriber = new PurchaseSubscriber();eventBus.register(purchaseSubscriber);

还有一个可以与@Subscribe结合使用的注释,即@AllowConcurrentEvents。 @AllowConcurrentEvents将处理程序方法标记为线程安全的,因此EventBus(很可能是AsyncEventBus)可以潜在地从同时线程调用事件处理程序。 我在单元测试中发现的一件有趣的事情是,如果处理程序方法没有@AllowConcurrentEvents批注,则即使使用AsyncEventBus,它也会按顺序调用事件的处理程序。 重要的是要注意,@ AllowConcurrentEvents不会将方法标记为事件处理程序,@ Subscribe批注仍需要存在。 最后,事件处理方法必须具有一个且只有一个参数,否则当您在EventBus中注册对象时,将抛出IllegalArgumentException。

发布事件

同样,使用EventBus发布事件也很简单。 在您要发送事件通知的代码部分中,调用EventBus.post,将为该事件对象注册的所有订阅者进行通知。

public void handleTransaction(){purchaseService.purchase(item,amount);eventBus.post(new CashPurchaseEvent(item,amount));....}

尽管这很明显,但是订阅类和发布类共享同一EventBus实例很重要,并且使用Guice或Spring帮助管理依赖项是有意义的。

有关事件处理程序的更多信息

EventBus的一项非常强大的功能是,您可以根据需要使处理程序正常运行或细化。 EventBus将为已发布事件对象的所有子类型和已实现的接口调用注册的订户。 例如,要处理所有事件,可以创建一个带有Object类型参数的事件处理程序。 要仅处理单个事件,请创建一个特定于类型的处理程序。 为了帮助说明,请考虑以下简单事件层次结构:

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;}
}

以下是相应的事件处理类:

//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) {.....}
}

如果需要捕获各种各样的事件类型,则替代方法是在一个类中具有多个事件处理方法。 拥有多个处理程序可能是一个更好的解决方案,因为您不必对事件对象参数进行任何“ instanceof”检查。 这是我的单元测试中的一个简单示例:

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);}
....

测试中

由于事件处理程序只是普通方法,因此可以通过在测试用例中实例化一个EventBus或通过传递适当的事件对象来模拟EventBus来轻松对其进行测试。 当使用EventBus时,我发现很容易:

  • 忘记在EventBus中注册订阅对象
  • 忽略添加@Subscribe批注。

如果似乎未调用事件处理程序,请首先检查这两个错误。
一种有用的调试技术是订阅DeadEvent类。 EventBus将在DeadEvent实例中包装任何没有处理程序的已发布事件。 DeadEvent提供了getEvent方法,该方法返回原始事件对象。

结论

Guava EventBus类为标准Java事件处理机制提供了一种有吸引力且有用的替代方法。 希望读者会发现EventBus像我一样有用。 一如既往地欢迎提出意见和建议。

资源资源

  • EventBus API
  • 番石榴API
  • 样例代码
  • 活动合作

参考:来自我们的JCG合作伙伴 Bill Bejeck的Google Guava EventBus进行事件编程,来自Random Thoughts On Coding博客。

翻译自: https://www.javacodegeeks.com/2012/11/google-guava-eventbus-for-event-programming.html

Google Guava EventBus用于事件编程相关推荐

  1. Google Guava EventBus和Java 7 WatchService用于事件编程

    这篇文章将介绍如何使用Guava EventBus将更改发布到Java 7 WatchService检测到的目录或子目录中. Guava EventBus是向应用程序添加发布/订阅通信的好方法. Ja ...

  2. [Google Guava] 4-函数式编程

    原文链接 译文链接 译者:沈义扬,校对:丁一 注意事项 截至JDK7,Java中也只能通过笨拙冗长的匿名类来达到近似函数式编程的效果.预计JDK8中会有所改变,但Guava现在就想给JDK5以上用户提 ...

  3. Google Guava官方教程(中文版)gu

    Google Guava官方教程(中文版) 原文链接  译文链接 译者: 沈义扬,罗立树,何一昕,武祖  校对:方腾飞 引言 Guava工程包含了若干被Google的 Java项目广泛依赖 的核心库, ...

  4. Google Guava的EventBus(事件总线)基本使用

            EventBus是Google.Guava提供的消息发布-订阅组件,采用的是观察者模式(生产/消费者编程模型), 实现了多组件之间通信的解耦合,事件产生方和事件消费方实现解耦分离,提升 ...

  5. Google guava 事件总线 EventBus 进程内消息队列

    Google guava 事件总线 EventBus 创建事件总线流程 码代码 引入依赖 一个简单的事件处理 监听者 创建事件生产者总线.注册事件监听者.发送事件 运行结果 扩展 多个事件监听者加De ...

  6. EventBus 事件机制详解(Google Guava)

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 概念 1. 事件本身 2. 发布事件的对象 3. 接收事件的对象 4. 验证结果 概念 使用EventBus(Guava提供 ...

  7. 【编程实践】Google Guava 极简教程

    前言 Guava 工程包含了若干被 Google 的 Java 项目广泛依赖 的核心库,我们希望通过此文档为 Guava 中最流行和最强大的功能,提供更具可读性和解释性的说明. 适用人群 本教程是基础 ...

  8. 为什么我不建议你用阿里巴巴Java规范,而使用 Google Guava 编程?

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 来自 | 张丰哲 链接 | www.jianshu.com ...

  9. 为什么推荐 Java 程序员使用 Google Guava 编程

    点击上方"方志朋",选择"设为星标" 做积极的人,而不是积极废人 来自 | 张丰哲 链接 | www.jianshu.com/p/97778b21bd00 前言 ...

最新文章

  1. linux学习笔记四:安装lsusb
  2. godep的save和update
  3. python update_python 字典中的Update()函数
  4. DBUtils、连接池
  5. linux中python安装_linux环境下的python安装过程图解(含setuptools)
  6. JavaScript instanceof 运算符深入剖析【转载】
  7. 【华为云技术分享】《跟唐老师学习云网络》 - 我的网络概念
  8. 如果你需要品质背景素材,看过来
  9. JavaScript小技巧总结
  10. 366万常用的中 txt 网盘_人间值得 – 中村恒子 pdf+azw3+epub+mobi+txt+docx|百度网盘资源分享...
  11. 湖北省大数据发展行动计划(2016-2020年)
  12. Vue表情包输入组件
  13. spss可以关键词词频分析吗_词频分析研究的现状、方法及工具,你值得拥有
  14. 卡诺图简单逻辑化简与五变量卡诺图化简
  15. RSF 分布式服务框架设计:线程模型
  16. 一、线性表的顺序存储和基本运算
  17. 使用WEX5移动开发工具制作仿淘宝APP
  18. Chrome 66之后禁止网页声音自动播放问题解决
  19. 小心做好个人隐私保护!别让笔记本电脑成为隐私泄露的“间谍”
  20. Milk Measurement

热门文章

  1. (转)linux上nginx源码编译安装
  2. 转-Kafka【第一篇】Kafka集群搭建
  3. java设计模式适配器模式_Java中的适配器设计模式
  4. javax线程池超时结束_没有Javax的Jakarta EE:这次世界也不会结束
  5. java中qrcode_如何在Java中使用QRGen创建QRCode
  6. java 多线程和并行编程_Java 8中的并行和异步编程
  7. java ee打印功能_Java EE 8的前5个新功能
  8. 使JavaDoc保持最新状态的工具
  9. 旧访客设计模式的新生活
  10. junit 5测试异常处理_在JUnit中处理异常的3种方式。 选择哪一个?