[Guava] EventBus

1.  发布-订阅模式

发布-订阅模式(publish-subscribe)是一种编程范式,发布方不发布消息给特定的接收方,而是由订阅方选择性接收。这使得发布方和订阅方相对独立,减少了耦合性。

在发布-订阅模式中,有以下几个难点:

1)如何区分或分配订阅者关注的消息;

2)发布者如何将消息提交给对应订阅者;

下图描述Guava EventBus对发布-订阅模式的实现。

2. 订阅者注册

下面是简单的订阅者实现:

// 订阅者
public class Subscriber  {
	@Subscribe
	public void process(String event) {
		System.out.print(event);
	}
}

注册订阅者:

// 消息订阅
EventBus eventBus = new EventBus();
eventBus.register(new Subscriber());

Guava EventBus中有关注册的流程:

Guava EventBus中有关注册的代码:

// SubscriberRegistry.register()
void register(Object listener) {
    // 查找订阅者中有Subscribe注解的方法
    // findAllSubscribers返回值: 函数参数类型-{EventBus,listener,有Subscribe注解的方法}
    Multimap<Class<?>, Subscriber> listenerMethods = findAllSubscribers(listener);

    for (Map.Entry<Class<?>, Collection<Subscriber>> entry : listenerMethods.asMap().entrySet()) {
      Class<?> eventType = entry.getKey();
      Collection<Subscriber> eventMethodsInListener = entry.getValue();

      // 所有订阅者
      CopyOnWriteArraySet<Subscriber> eventSubscribers = subscribers.get(eventType);

      if (eventSubscribers == null) {
        CopyOnWriteArraySet<Subscriber> newSet = new CopyOnWriteArraySet<Subscriber>();
        eventSubscribers = MoreObjects.firstNonNull(
            subscribers.putIfAbsent(eventType, newSet), newSet);
      }

      eventSubscribers.addAll(eventMethodsInListener);
    }
  }

  

3. 事件提交&处理

eventBus.post("Hello, EventBus");

Guava EventBus中消息提交和处理流程:

  

Guava EventBus中消息提交和处理代码:

// EventBus.post(..)
public void post(Object event) {
    // 查找相关订阅者
    Iterator<Subscriber> eventSubscribers = subscribers.getSubscribers(event);

   if (eventSubscribers.hasNext()) {
      // 事件处理类型
      dispatcher.dispatch(event, eventSubscribers);
    } else if (!(event instanceof DeadEvent)) {
      // the event had no subscribers and was not itself a DeadEvent
      post(new DeadEvent(this, event));
    }
  }

  

Dispatcher有以下几种:

1. PerThreadQueuedDispatcher : 按照事件提交顺序进行处理(a breadth-first dispatch)。 // EventBus默认分配类型

2. LegacyAsyncDispatcher:若订阅者处理函数上有AllowConcurrentEvents注解,则使用线程中对象进行多线程并行处理;否则将使用同步处理。// AsyncEventBus默认分配类型

class Subscriber {
  static Subscriber create(EventBus bus, Object listener, Method method) {
    return method.getAnnotation(AllowConcurrentEvents.class) != null
        ? new Subscriber(bus, listener, method)
        : new SynchronizedSubscriber(bus, listener, method);
  }
}
Subscriber中dispatchEvent中处理方法:
final void dispatchEvent(final Object event) {
    executor.execute(new Runnable() {
      @Override
      public void run() {
         method.invoke(target, checkNotNull(event));
    });
  }

3. ImmediateDispatcher:立即将事件提交给对应的订阅者(a depth-first dispatch)

时间: 2024-11-05 12:27:38

[Guava] EventBus的相关文章

设计模式:Observer(观察者)—— Guava EventBus

本文分为三个部分: Observer(观察者) Guava EventBus详解 Guava EventBus使用示例 1. Observer(观察者) 1.1 背景 我们设计系统时,常常会将系统分割为一系列相互协作的类,使得这些类之间可以各自独立地复用,系统整体结构也会比较清晰.这是一种最基本的面向对象的设计方式,大多数情况下也非常有效.但是,如果这些相互协作的类之间的“协作”关系比较复杂,那么就会有副作用:需要维护这些类对象间的状态一致性. 我们以一个数据可视化系统为例来说明: (1)数据可

Guava库学习:学习Guava EventBus(二)EventBus 事件订阅示例

原文地址:Guava库学习:学习Guava EventBus(二)EventBus 事件订阅示例 上一篇Guava库学习:学习Guava EventBus(一)EventBus,我们简单的对Guava基于事件的编程进行了介绍,学习和了解了EventBus类的使用,本篇起,我们通过一系列的示例代码深入的学习EventBus类,本篇学习Guava EventBus(二)EventBus 事件订阅示例.     订阅Subscribe 首先,我们假定定义了如下所示的TradeAccountEvent类

guava eventbus代码分析

分析guava eventbus之前,先看一下传统观察者模式的写法: Subject接口是抽象主题,相当于被观察者,它持有一个监听者observer的列表,attach方法往这个列表里面注册监听者,detach方法注销监听者,notify方法用于事件发生时通知到列表中的监听者 通常在notify的实现方法中会调用监听者的update方法. Observer是抽象观察者,带一个update方法,update方法被具体主题的notify方法调用.

Guava库学习:学习Guava EventBus(一)EventBus

原文地址:http://www.xx566.com/detail/184.html 在软件开发过程中,对象信息的分享以及相互直接的协作是必须的,困难在于确保对象之间的沟通是有效完成的,而不是拥有成本高度耦合的组件.当对象对其他组件的责任有太多的细节时,它被认为是高度耦合的.当一个应用程序有高度的耦合,维护将变得非常具有挑战,任何变化都将带来涟漪效应.为了解决这一类的软件设计问题,我们就需要基于事件的编程.本篇,我们就来学习Guava 基于事件的编程,Guava EventBus(一)EventB

Guava - EventBus(事件总线)

Guava在guava-libraries中为我们提供了事件总线EventBus库,它是事件发布订阅模式的实现,让我们能在领域驱动设计(DDD)中以事件的弱引用本质对我们的模块和领域边界很好的解耦设计. 不再多的废话,直奔Guava EventBus主题.首先Guava为我们提供了同步事件EventBus和异步实现AsyncEventBus两个事件总线,他们都不是单例的,官方理由是并不想我们我们的使用方式.当然如果我们想其为单例,我们可以很容易封装它,一个单例模式保证只创建一个实例就对了. 下面

Guava ---- EventBus事件驱动模型

在软件开发过程中, 难免有信息的共享或者对象间的协作. 怎样让对象间信息共享高效, 而且耦合性低. 这是一个难题. 而耦合性高将带来编码改动牵一发而动全身的连锁效应. Spring的风靡正是由于攻克了高耦合问题. 本篇介绍的EventBus中也用到了Spring中的依赖注入. 来进行对象和对象间的解耦(如@Subscribe). Guava解决高耦合採用的是事件驱动模型的思路. 对象能够订阅(subscribe)特定的事件或者公布(publish)特定的事件去被消费. 从以下的代码能够看出, E

让开发效率爆表的Guava ---- EventBus事件驱动模型

在软件开发过程中, 难免有信息的共享或者对象间的协作. 如何让对象间信息共享高效, 并且耦合性低, 这是一个难题. 而耦合性高将带来编码修改牵一发而动全身的连锁效应, Spring的风靡正是因为解决了高耦合问题. 本篇介绍的EventBus中也用到了Spring中的依赖注入, 来进行对象和对象间的解耦(如@Subscribe). Guava解决高耦合采用的是事件驱动模型的思路, 对象可以订阅(subscribe)特定的事件或者发布(publish)特定的事件去被消费. 从下面的代码可以看出, E

guava eventbus代码分析(二)

---恢复内容开始--- 我们分析下EventBus的核心方法 post方法,直接贴代码 1 public void post(Object event) { 2 Iterator<Subscriber> eventSubscribers = subscribers.getSubscribers(event); 3 if (eventSubscribers.hasNext()) { 4 dispatcher.dispatch(event, eventSubscribers); 5 } else

Guava: 事件总线EventBus

EventBus 直译过来就是事件总线,它使用发布订阅模式支持组件之间的通信,不需要显式地注册回调,比观察者模式更灵活,可用于替换Java中传统的事件监听模式,EventBus的作用就是解耦,它不是通用的发布订阅系统,也不能用于进程间通信.可用于Android的EventBus库主要有这几个:Google出品的Guava,Guava是一个庞大的库,EventBus 只是它附带的一个小功能,因此实际项目中使用并不多.用的最多的是greenrobot/EventBus,这个库的优点是接口简洁,集成方