详解Guava中EventBus的使用
作者:指北君 发布时间:2021-09-13 07:36:34
Guava EventBus
EventBus是Guava的事件处理机制,是设计模式中观察者模式(生产/消费者编程模型)的优雅实现。对于事件监听和发布订阅模式,EventBus使用非常简单便捷。
如果你做过CS的开发,下面这段代码可能会比较熟悉。
Button button = new Button("确定");
button.addListener( new Listener(){
...
public void onClick(Event event){
//
}
...
} );
为按钮注册事件监听,当按钮被点击时,则触发监听中相应的回调。在上面的代码中,有三个角色事件(Event),事件源(Button),监听(Listener),按钮作为事件源,当点击行为触发时,会将该行为封装成对应的点击事件,并根据行为类型将事件传递到响应的 * 上, 这也就是我们常说的 * 模式。
使用场景
实现消息生产者与消费者间的解耦,对应事件源与 * ,而消息则是事件
通过事件驱动业务流程扭转,通过异步执行机制实现代码非阻塞执行
扩展主线外的分支业务,减少代码的侵入,比如各个环节的消息通知、短信提醒等
实现消息广播到不同的模块中
示例
订单支付时的消息发送
// 商品
public class ProductOrder {
private String user; // 用户
private String product; // 商品
private double amount; // 金额
@Override
public String toString() {
return String.format("用户:%s购买了商品:%s,总金额:%s", user, product, amount);
}
}
// 事件
@Data
@AllArgsConstructor
public static class CreateOrderEvent implements OrderEvent{
private ProductOrder order;
}
// 监听
public static class CreateOrderListener{
@Subscribe
public void onEvent(CreateOrderEvent event) {
log.info("创建订单:{}", event.getOrder());
}
}
测试: 我们可以定义各种事件,比如订单创建、订单取消、订单支付... 只需要简单的三个步骤即可:
// 1. 创建事件总线
EventBus eventBus = new EventBus( ProductOrder.class.getName() );
// 2. 注册事件监听
eventBus.register( new CreateOrderListener() );
eventBus.register( new PayOrderListener() );
eventBus.register( new CancelOrderListener() );
eventBus.register( new RenewOrderListener() );
// 3. 发送事件通知
eventBus.post(new ProductOrder.CreateOrderEvent(order));
TimeUnit.SECONDS.sleep(1);
eventBus.post(new ProductOrder.CancelOrderEvent(order));
TimeUnit.SECONDS.sleep(1);
eventBus.post(new ProductOrder.RenewOrderEvent(order));
TimeUnit.SECONDS.sleep(1);
eventBus.post(new ProductOrder.PayOrderEvent(order));
TimeUnit.SECONDS.sleep(5);
eventBus.post(new ProductOrder.ReturnOrderEvent(order));
同时我们可以通过AsyncEventBus建立事件异步总线,这样在事件被触发时,可以异步通知监听者完成事件回调,以此来提高响应速度。
核心
EventBus
事件总线,可以理解为事件与 * 的上下文,主要实现事件的注册、事件的分发、以及 * 的回调,主要提供的方法包括:
register 注册监听,将 * 注册到事件总线,通过注解@Subscribe通知其监听的事件类型(第一个方法参数类型)
unregister 卸载监听,从事件总线移除监听
post 发送事件通知,根据post事件类型,找到所有订阅了该类型事件的 * ,并将事件推送到 * 对应的监听方法
Subscribe
通过@Subscribe标识 * 所关注的事件类型
Event
可以是任何对象,当然不建议将基础类型或String作为事件类型,这样就没法做到按类型区分了
通过上面的图就可以很清楚各个各个组件的职责,以及如何通过事件总线完成事件向监听的传播,最终基于事件回调机制完成消息传递。基于事件驱动的服务模型
上面这种结构的图形是不是在很多位置都见过,这是一种经典的设计模式。试想一下,我们不通过事件驱动行为时,一般你们怎么写代码,通过ifelse?或者其他有着异曲同工的 实现方法,目的最后都是一样。基于Guava提供的工具,我们不仅在使用时只需要简单的三个步骤就能实现,同样,当需要屏蔽该功能时只需要去掉register一行即可,对整体功能 也没有任何的影响。
在我们引入某种设计模式,某种架构模型时,总的目的都是为了降低代码模块间的耦合度,提升代码整体的可读性,最终让代码能够易于维护性,或者有一定的复用性。
来源:https://mp.weixin.qq.com/s/dqbnN5YmfWSZVUK4EcASPg


猜你喜欢
- 锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized 和 ReentrantLock等等 ) 。这些
- springcloud微服务包含的技术种类众多,eureka作为其注册中心,一直处于主流,但在今年已经处于永久停更状态,但其优秀的能力还是值
- 多选和单选的不同之处单选的时候,选中一个就可以直接把结果返回,因此本身底部弹窗无需状态管理。但到多选的时候,需要知道当前选中的选项,有选项被
- 在Web应用系统开发中,文件上传和下载功能是非常常用的
- 前言RadioGroup是继承LinearLayout,只支持横向或者竖向两种布局。所以在某些情况,比如多行多列布局,RadioGroup就
- 预览效果图:需要权限:<uses-permission android:name="com.android.launcher
- 最近在一本J2EE的书中看到了很不错的对集合框架的说明文章,筛选后发上来和大家共享,集合框架提供管理对象集合的接口和类.它包含接口,类,算法
- 本文实例讲述了Android使用WebView.loadUri()打开网页的方法。分享给大家供大家参考,具体如下:程序如下所示:import
- 项目中遇到这样个需求:app的功能导航需要可拖动排序,类似头条中的频道拖动管理。效果如下,gif不是很顺畅,真机会好很多。虽然类似的文章网上
- 本文实例讲述了Android实现整理PackageManager获取所有安装程序信息的方法。分享给大家供大家参考,具体如下:List<
- public class MainActivity extends Activity { public RadioGroup mR
- 本文实例讲述了Android操作SQLite数据库(增、删、改、查、分页等)及ListView显示数据的方法。分享给大家供大家参考,具体如下
- 一、insert1.插入操作public class CRUDTests { @Autowired
- 本文实例为大家分享了Android点击缩略图放大效果的具体代码,供大家参考,具体内容如下import android.animation.A
- 前言Feign是Netflix开源的声明式HTTP客户端,致力于让编写http client更加简单,Feign可以通过声明接口自动构造请求
- Android上杀掉进程的方式有两种,分别是System.exit(0)和Process.killProcess(Process.myPid
- Spring MVC 启动的关键流程我们已经学习了 Handler 与 HandlerMapping,还未掌握的小伙伴可以翻看前面的文章进行
- 本文实例为大家分享了Android实现京东首页效果的具体代码,供大家参考,具体内容如下1.效果图:2.布局源码链接<?xml vers
- 一、前言虽然jdk1.9版本已经问世,但是许多其他的配套设施并不一定支持jdk1.9版本,所以这里仅带领你配置jdk1.8。而jdk1.9的
- if语句一个if语句包含一个布尔表达式和一条或多条语句。语法If语句的用语法如下:if(布尔表达式){ //如果布尔