Google Guava EventBus

本文介绍了Google Guava中的EventBus,它简化了处理生产/消费者编程模型的方式。通过使用EventBus,开发者可以更轻松地订阅消息,无需继承特定接口,只需在方法上添加@Subscribe注解。本文提供了示例代码,展示了如何定义消息封装类、事件监听器类及测试用例。还讨论了如何使用MultiListener订阅多个消息、DeadEvent处理以及Event的继承特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在Google Guava 10版本引入了EventBus, 它主要用来简化我们处理生产/消费者编程模型. 

基本用法 
使用Guava之后, 如果要订阅消息, 就不用再继承指定的接口, 只需要在指定的方法上加上@Subscribe注解即可: 

Java代码  收藏代码
  1. public class EventListener {  
  2.    
  3.     public int lastMessage = 0;  
  4.    
  5.     @Subscribe  
  6.     public void listen(OurTestEvent event) {  
  7.         lastMessage = event.getMessage();  
  8.     }  
  9.    
  10.     public int getLastMessage() {  
  11.         return lastMessage;  
  12.     }  
  13. }  



上面的lastMessage用来接收消息. 

下面定义的类用来对消息进行封装: 

Java代码  收藏代码
  1. public class OurTestEvent {  
  2.    
  3.     private final int message;  
  4.    
  5.     public OurTestEvent(int message) {  
  6.         this.message = message;  
  7.     }  
  8.    
  9.     public int getMessage() {  
  10.         return message;  
  11.     }  
  12. }  



通过写一个测试来了解EventBus如何工作: 

Java代码  收藏代码
  1. @Test  
  2. public void shouldReceiveEvent() throws Exception {  
  3.    
  4.     // given  
  5.     EventBus eventBus = new EventBus("test");  
  6.     EventListener listener = new EventListener();  
  7.    
  8.     eventBus.register(listener);  
  9.    
  10.     // when  
  11.     eventBus.post(new OurTestEvent(200));  
  12.    
  13.     // then  
  14.     assertThat(listener.getLastMessage()).isEqualTo(200);  
  15. }  



上面的测试是不是很简单? 

MultiListener的使用 

只需要在要订阅消息的方法上加上@Subscribe注解即可实现对多个消息的订阅: 

Java代码  收藏代码
  1. public class MultipleListener {  
  2.    
  3.     public Integer lastInteger;  
  4.     public Long lastLong;  
  5.    
  6.     @Subscribe  
  7.     public void listenInteger(Integer event) {  
  8.         lastInteger = event;  
  9.     }  
  10.    
  11.     @Subscribe  
  12.     public void listenLong(Long event) {  
  13.         lastLong = event;  
  14.     }  
  15.    
  16.     public Integer getLastInteger() {  
  17.         return lastInteger;  
  18.     }  
  19.    
  20.     public Long getLastLong() {  
  21.         return lastLong;  
  22.     }  
  23. }  



下面是对应的测试: 

Java代码  收藏代码
  1. @Test  
  2. public void shouldReceiveMultipleEvents() throws Exception {  
  3.    
  4.     // given  
  5.     EventBus eventBus = new EventBus("test");  
  6.     MultipleListener multiListener = new MultipleListener();  
  7.    
  8.     eventBus.register(multiListener);  
  9.    
  10.     // when  
  11.     eventBus.post(new Integer(100));  
  12.     eventBus.post(new Long(800));  
  13.    
  14.     // then  
  15.     assertThat(multiListener.getLastInteger()).isEqualTo(100);  
  16.     assertThat(multiListener.getLastLong()).isEqualTo(800L);  
  17. }  



高级用法 

1.Dead Event 

如果EventBus发送的消息都不是订阅者关心的称之为Dead Event. 看下面的例子: 

Java代码  收藏代码
  1. /** 
  2.  * Listener waiting for the event that any message was posted but not delivered to anyone 
  3.  */  
  4. public class DeadEventListener {  
  5.    
  6.     boolean notDelivered = false;  
  7.    
  8.     @Subscribe  
  9.     public void listen(DeadEvent event) {  
  10.         notDelivered = true;  
  11.     }  
  12.    
  13.     public boolean isNotDelivered() {  
  14.         return notDelivered;  
  15.     }  
  16. }  



下面是测试类: 

Java代码  收藏代码
  1. @Test  
  2. public void shouldDetectEventWithoutListeners() throws Exception {  
  3.    
  4.     // given  
  5.     EventBus eventBus = new EventBus("test");  
  6.    
  7.     DeadEventListener deadEventListener = new DeadEventListener();  
  8.     eventBus.register(deadEventListener);  
  9.    
  10.     // when  
  11.     eventBus.post(new OurTestEvent(200));  
  12.    
  13.     assertThat(deadEventListener.isNotDelivered()).isTrue();  
  14. }  



如果没有消息订阅者监听消息, EventBus将发送DeadEvent消息, 这时我们可以通过log的方式来记录这种状态. 

2.Event的继承 

如果Listener A监听Event A, 而Event A有一个子类Event B, 此时Listener A将同时接收Event A和B消息 

看下面的例子: 

Java代码  收藏代码
  1. public class NumberListener {  
  2.    
  3.     private Number lastMessage;  
  4.    
  5.     @Subscribe  
  6.     public void listen(Number integer) {  
  7.         lastMessage = integer;  
  8.     }  
  9.    
  10.     public Number getLastMessage() {  
  11.         return lastMessage;  
  12.     }  
  13. }  
  14.   
  15.       
  16. public class IntegerListener {  
  17.    
  18.     private Integer lastMessage;  
  19.    
  20.     @Subscribe  
  21.     public void listen(Integer integer) {  
  22.         lastMessage = integer;  
  23.     }  
  24.    
  25.     public Integer getLastMessage() {  
  26.         return lastMessage;  
  27.     }  
  28. }  



对应的测试类: 


Java代码  收藏代码
  1. @Test  
  2. public void shouldGetEventsFromSubclass() throws Exception {  
  3.    
  4.     // given  
  5.     EventBus eventBus = new EventBus("test");  
  6.     IntegerListener integerListener = new IntegerListener();  
  7.     NumberListener numberListener = new NumberListener();  
  8.     eventBus.register(integerListener);  
  9.     eventBus.register(numberListener);  
  10.    
  11.     // when  
  12.     eventBus.post(new Integer(100));  
  13.    
  14.     // then  
  15.     assertThat(integerListener.getLastMessage()).isEqualTo(100);  
  16.     assertThat(numberListener.getLastMessage()).isEqualTo(100);  
  17.    
  18.     //when  
  19.     eventBus.post(new Long(200L));  
  20.    
  21.     // then  
  22.     // this one should has the old value as it listens only for Integers  
  23.     assertThat(integerListener.getLastMessage()).isEqualTo(100);  
  24.     assertThat(numberListener.getLastMessage()).isEqualTo(200L);  
  25. }  

 

### Google Guava EventBus 库文档与使用示例 #### 简介 Guava 的 `EventBus` 是一种发布-订阅模式的事件总线实现,允许组件之间解耦通信。通过定义事件类并注册监听器来处理这些事件,可以简化应用程序内部的消息传递机制[^1]。 #### 基本概念 - **事件 (Events)**: 表示应用内发生的特定情况的对象实例。 - **监听者 (Listeners)**: 实现方法响应某些类型的事件对象。 - **发布者 (Publisher)**: 负责创建并向 `EventBus` 发布新事件实例的实体。 - **订阅者 (Subscriber)**: 注册到 `EventBus` 上以接收感兴趣类型事件的方法或函数。 #### 使用说明 ##### 创建和配置 `EventBus` ```java // 初始化一个新的 EventBus 对象 EventBus eventBus = new EventBus(); ``` ##### 定义事件类 ```java public class MyCustomEvent { private final String message; public MyCustomEvent(String msg) { this.message = msg; } @Override public String toString() { return "MyCustomEvent{" + "message='" + message + '\'' + '}'; } } ``` ##### 编写监听者逻辑 ```java public class EventListener { // 订阅该事件的方法名前需加上@Subscribe注解 @Subscribe public void handleMyCustomEvent(MyCustomEvent event){ System.out.println("Received custom event:" +event); } } ``` ##### 将监听者注册至 `EventBus` ```java EventListener listenerInstance = new EventListener(); // 向 EventBus 中添加监听者 eventBus.register(listenerInstance); ``` ##### 发送事件给所有已注册的监听者 ```java // 构造一个自定义事件实例 MyCustomEvent myEvent = new MyCustomEvent("Hello, world!"); // 通过调用 post 方法向所有的监听者广播此事件 eventBus.post(myEvent); ``` 以上就是如何利用 Guava 提供的 `EventBus` 来构建松散耦合的应用程序模块间通讯的方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值