Guava

来源:互联网 发布:乐乎城市青年公寓黄村 编辑:程序博客网 时间:2024/06/08 20:04

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 tmallorder 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();        }      }    }
原创粉丝点击