Google_Guava官方教程(中文版)11-事件总线
reprint
Fri Oct 01 20:48:00 CST 2010

事件总线

传统上,Java的进程内事件分发都是通过发布者和订阅者之间的显式注册实现的。设计 EventBus就是为了取代这种显示注册方式,使组件间有了更好的解耦。EventBus不是通用型 的发布-订阅实现,不适用于进程间通信。

范例

// Class is typically registered by the container. class EventBusChangeRecorder {     @Subscribe public void recordCustomerChange(ChangeEvent e) {         recordChange(e.getChange());     } } // somewhere during initialization eventBus.register(new EventBusChangeRecorder()); // much later public void changeCustomer() {     ChangeEvent event = getChangeEvent();     eventBus.post(event); }

一分钟指南

把已有的进程内事件分发系统迁移到EventBus非常简单。

事件监听者[Listeners]

事件生产者[Producers]

术语表

事件总线系统使用以下术语描述事件分发:

事件 可以向事件总线发布的对象
订阅 向事件总线注册监听者以接受事件的行为
监听者 提供一个处理方法,希望接受和处理事件的对象
处理方法 监听者提供的公共方法,事件总线使用该方法向监听者发送事件;该方法应该用Subscribe注解
发布消息 通过事件总线向所有匹配的监听者提供事件

常见问题解答[FAQ]

class ChangeRecorder {

    void setCustomer(Customer cust) {

        cust.addChangeListener(new ChangeListener() {

            public void customerChanged(ChangeEvent e) {

                recordChange(e.getChange());

            }

        };

    }

}

//这个监听者类通常由容器注册给事件总线

class EventBusChangeRecorder {

    @Subscribe public void recordCustomerChange(ChangeEvent e) {

        recordChange(e.getChange());

    }

}

第二种实现的业务意图明显更加清晰:没有多余的代码,并且处理方法的名字是清晰和有意 义的。

因为类型擦除,Java禁止一个类使用不同的类型参数多次实现同一个泛型接口(即不可能出 现MultiHandler implements Handler<Type1>, Handler<Type2>)。这比起传统的Java事件 机制也是巨大的退步,至少传统的Java Swing监听者接口使用了不同的方法把不同的事件区 分开。

其它文章