使用guava中的EventBus构建内存级别的事件引擎

本文介绍了Guava库中的EventBus组件,通过实例演示了如何定义事件、注册事件处理器及事件的分发流程。探讨了同步与异步处理机制,并展示了如何在不同场景下运用EventBus实现事件驱动架构。

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

这个EventBus是guava中比较给力的一个类,从字面上看是事件总线,解决了传统的观察这模式的问题,使用比较灵活方便。最近打算搞一个轻量级的事件驱动引擎,重点参照了这个类EventBus,如果是内存级别的事件分发或者MQ,推荐直接用EventBus。

 

关于EventBus中的几个问题?

1、  事件定义:任意的对象即可;

2、  事件处理器的注册:事件处理的方法,添加注解即可,然后事件处理器的对象注册到总线中,总线维护一个事件和事件处理器的关联关系,在内存中;

3、  事件的处理过程:同步处理和异步处理,事件提交之后,事件队列维护在本地缓存,同步的方式直接当前线程去执行,异步的处理策略是在初始化事件总线的时候就搞了一个线程池出来,由线程池去异步执行;

4、  EventBus就开放了三个方法,register/post/unregister

5、  为什么会有unregister

在99.99%的使用场景中,是不会在runtime的时候去register/unregister某个observer的,在spring的环境,也是在init的时候做register/unregister。不过做framework就必须要考虑这0.01%的使用场景。

 

一个简单的例子:

1、一个事件的定义(任何对象都可以是事件)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public  class  SignEvent {   
     private  String companyName;
     private  String signName;   
     private  Date signDate;
     public  SignEvent(String name,String signName, Date signDate) {
         super ();
         this .companyName = name;
         this .signName = signName;
         this .signDate = signDate;
     }  
     public  String getMessage(){
         StringBuilder sb =  new  StringBuilder();
         sb.append( "物流公司:" ).append( this .companyName);
         sb.append( "签收人:" ).append(signName).append( ",签收日期:" ).append(signDate);
         return  sb.toString();
     }
}

2、定义两个事件监听器,添加注解做事件的订阅

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public  class  YTOEventListener {
     @Subscribe
     public  void  consign(SignEvent signEvent){
         if (signEvent.getCompanyName().equalsIgnoreCase( "YTO" )){
             System.out.println( "YTO。。。开始发货" );
             System.out.println(signEvent.getMessage());
         }
     }
     
     @Subscribe
     public  void  delivery(SignEvent signEvent){
         if (signEvent.getCompanyName().equalsIgnoreCase( "YTO" )){
             System.out.println( "YTO。。。开始投递" );
         }
     }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public  class  SFEventListener { 
     @Subscribe
     public  void  consign(SignEvent signEvent){
         if (signEvent.getCompanyName().equalsIgnoreCase( "SF" )){
             System.out.println( "SF。。。开始发货" );
             System.out.println(signEvent.getMessage());
         }
     }  
     @Subscribe
     public  void  delivery(SignEvent signEvent){
         if (signEvent.getCompanyName().equalsIgnoreCase( "SF" )){
             System.out.println( "SF。。。开始投递" );
         }
     }
}

3、EventBus的例子,包含时间的注册以及事件的提交

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public  class  EventBusTest {
     
     public  static  void  siginalThreadConsumer(){
 
         EventBus bus =  new  EventBus( "iamzhongyong" );       
         SFEventListener sf =  new  SFEventListener();
         YTOEventListener yto =  new  YTOEventListener();
         bus.register(sf);
         bus.register(yto);     
         SignEvent sign1 =  new  SignEvent( "SF" , "比熊啊" , new  Date());
         bus.post(sign1);       
         SignEvent sign2 =  new  SignEvent( "YTO" , "你妹的" , new  Date());
         bus.post(sign2);   
     }
     
     public  static  void  multiThread(){
         EventBus bus =  new  AsyncEventBus(Executors.newFixedThreadPool( 3 ));     
         SFEventListener sf =  new  SFEventListener();
         YTOEventListener yto =  new  YTOEventListener();
         bus.register(sf);
         bus.register(yto);
         SignEvent sign1 =  new  SignEvent( "SF" , "比熊啊" , new  Date());
         bus.post(sign1);       
         SignEvent sign2 =  new  SignEvent( "YTO" , "你妹的" , new  Date());
         bus.post(sign2);   
     }
 
     public  static  void  main(String[] args) {       
         EventBusTest.siginalThreadConsumer();
         EventBusTest.multiThread();
     }
}

 

事件驱动架构的官方解释是啥?

这里看了一下官方wiki的介绍,http://en.wikipedia.org/wiki/Event-driven_architecture 

 

事件驱动架构的包含哪些组件?

在官方的解释上加了一些自己的理解

 

### 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、付费专栏及课程。

余额充值