Guava - EventBus

EventBus

EventBus 是事件发布与订阅模式一种实现,与传统的Java Event 模型的区别是:

监听器的管理
  • 传统的 Java events: 需要写代码管理对象的监听器集合, 包括同步问题, 或者使用像 EventListenerList的工具.
  • 使用 EventBus: 这些EventBus 都为你做好了
事件的派发
  • 传统的 Java events:需要写代码将每个事件派发给事件监听器。
  • 使用 EventBus:只需要调用EventBus.post(Object)就可以了,EventBus会将事件派发给对应的事件监听器
样例:
  • 订单domain
public class Order {
    private String status;
    private String type;

    public Order(String status, String type) { this.status = status; this.type = type; }
    public String getStatus() { return status; }
    public void setStatus(String status) { this.status = status; }
    public String getType() { return type; }
    public void setType(String type) { this.type = type; }
}
  • 订单事件
public class OrderEvent {
    private Order order;

    public OrderEvent(Order order) { this.order = order; }
    public Order getOrder() { return order; }
    public void setOrder(Order order) { this.order = order; }
}
  • 订单事件监听器
public class OrderEventListener {

    @Subscribe
    public void orderStateChange(OrderEvent orderEvent) {

        Order order = orderEvent.getOrder();

        System.out.println(MessageFormat.format("order status change to {0}", order.getStatus()));
    }
}
  • 样例:
public class Demo {
    public static void main(String[] args) {

        EventBus eventBus = new EventBus("order");
        eventBus.register(new OrderEventListener());

        Order order = new Order("paid", "tmall");
        OrderEvent orderEvent = new OrderEvent(order);

        eventBus.post(orderEvent);
    }
}
输出:
order status change to paid

可以看到订单事件和事件监听器没有实现任何接口,仅仅是使用了@Subscribe注解表明监听事件。所有的事件监听器管理和事件的派发EventBus都为我们做好了

监听多个事件

只要在监听器增加一个方法就可以了

public class OrderEventListener {

    @Subscribe
    public void orderStateChange(OrderEvent orderEvent) {

        Order order = orderEvent.getOrder();

        System.out.println(MessageFormat.format("order status change to {0}", order.getStatus()));
    }

    @Subscribe
    public void orderTypeChange(OrderEvent orderEvent) {

        Order order = orderEvent.getOrder();

        System.out.println(MessageFormat.format("order type change to {0}", order.getType()));
    }
}

修改后的上述程序的输出:

order type change to tmall
order status change to paid
注册

EventBus里有一个SubscriberRegistry,当向EventBus注册监听器的时候,SubscriberRegistry会根据监听器的Class查找其带有@Subscribe注解的方法,保存到SubscriberRegistry的属性subscribers(ConcurrentMap)中

void register(Object listener) {
        //查找所有的订阅者,就是根据监听器的class查找带有@Subscribe注解的方法
        Multimap listenerMethods = this.findAllSubscribers(listener);

        Collection eventMethodsInListener;
        CopyOnWriteArraySet eventSubscribers;
        for(Iterator var3 = listenerMethods.asMap().entrySet().iterator(); var3.hasNext(); eventSubscribers.addAll(eventMethodsInListener)) {
            Entry entry = (Entry)var3.next();
            Class eventType = (Class)entry.getKey();
            eventMethodsInListener = (Collection)entry.getValue();
            eventSubscribers = (CopyOnWriteArraySet)this.subscribers.get(eventType);
            if(eventSubscribers == null) {
                CopyOnWriteArraySet newSet = new CopyOnWriteArraySet();
                //保存到ConcurrentMap中
                eventSubscribers = (CopyOnWriteArraySet)MoreObjects.firstNonNull(this.subscribers.putIfAbsent(eventType, newSet), newSet);
            }
        }

    }
派发

EventBus里有一个和Dispatcher,当向EventBus发布事件的时候,Dispatcher会将事件派发给对应的事件监听器

public void post(Object event) {
        //获取对应的事件监听器
        Iterator eventSubscribers = this.subscribers.getSubscribers(event);
        if(eventSubscribers.hasNext()) {
            this.dispatcher.dispatch(event, eventSubscribers);
        } else if(!(event instanceof DeadEvent)) {
            this.post(new DeadEvent(this, event));
        }

    }
Iterator<Subscriber> getSubscribers(Object event) {
    //事件类型
    ImmutableSet<Class<?>> eventTypes = flattenHierarchy(event.getClass());

    List<Iterator<Subscriber>> subscriberIterators =
        Lists.newArrayListWithCapacity(eventTypes.size());

    for (Class<?> eventType : eventTypes) {

      //获取事件监听器
      CopyOnWriteArraySet<Subscriber> eventSubscribers = subscribers.get(eventType);
      if (eventSubscribers != null) {
        // eager no-copy snapshot
        subscriberIterators.add(eventSubscribers.iterator());
      }
    }

事件派发

void dispatch(Object event, Iterator<Subscriber> subscribers) {
      checkNotNull(event);
      checkNotNull(subscribers);
      Queue<Event> queueForThread = queue.get();
      queueForThread.offer(new Event(event, subscribers));

      if (!dispatching.get()) {
        dispatching.set(true);
        try {
          Event nextEvent;
          while ((nextEvent = queueForThread.poll()) != null) {
            while (nextEvent.subscribers.hasNext()) {
              nextEvent.subscribers.next().dispatchEvent(nextEvent.event);
            }
          }
        } finally {
          dispatching.remove();
          queue.remove();
        }
      }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值