事件监听者[Listeners]
监听特定事件(如,CustomerChangeEvent):
- 传统实现:定义相应的事件监听者类,如CustomerChangeEventListener;
- EventBus实现:以CustomerChangeEvent为唯一参数创建方法,并用Subscribe注解标记。
把事件监听者注册到事件生产者:
- 传统实现:调用事件生产者的registerCustomerChangeEventListener方法;这些方法很少定义在公共接口中,因此开发者必须知道所有事件生产者的类型,才能正确地注册监听者;
- EventBus实现:在EventBus实例上调用EventBus.register(Object)方法;请保证事件生产者和监听者共享相同的EventBus实例。
按事件超类监听(如,EventObject甚至Object):
- 传统实现:很困难,需要开发者自己去实现匹配逻辑;
- EventBus实现:EventBus自动把事件分发给事件超类的监听者,并且允许监听者声明监听接口类型和泛型的通配符类型(wildcard,如 ? super XXX)。
检测没有监听者的事件:
- 传统实现:在每个事件分发方法中添加逻辑代码(也可能适用AOP);
- EventBus实现:监听DeadEvent;EventBus会把所有发布后没有监听者处理的事件包装为DeadEvent(对调试很便利)。
事件生产者[Producers]
管理和追踪监听者:
- 传统实现:用列表管理监听者,还要考虑线程同步;或者使用工具类,如EventListenerList;
- EventBus实现:EventBus内部已经实现了监听者管理。
向监听者分发事件:
- 传统实现:开发者自己写代码,包括事件类型匹配、异常处理、异步分发;
- EventBus实现:把事件传递给 EventBus.post(Object)方法。异步分发可以直接用EventBus的子类AsyncEventBus。
术语表
事件总线系统使用以下术语描述事件分发:
事件 | 可以向事件总线发布的对象 |
---|---|
订阅 | 向事件总线注册监听者以接受事件的行为 |
监听者 | 提供一个处理方法,希望接受和处理事件的对象 |
处理方法 | 监听者提供的公共方法,事件总线使用该方法向监听者发送事件;该方法应该用Subscribe注解 |
发布消息 | 通过事件总线向所有匹配的监听者提供事件 |
例1:
定义一个监听者:
public class SimpleListener {
@Subscribe
public void action(final String event){
System.out.println("action方法被执行了,接收到参数["+ event +"]");
}
}
定义一个生产者
public class SimpleEventBusExample {
public static void main(String[] args) {
EventBus eventBus = new EventBus();
//指定执行的监听者
eventBus.register(new SimpleListener());
eventBus.post("测试");
}
}
结果:
action方法被执行了,接收到参数[测试]
例2:如果一个类里面有两个监听者,但是参数不一样(基本类型参数需要使用包装类型)
定义两个参数类型不同的监听者
public class SimpleListener {
@Subscribe
public void action1(final String event){
System.out.println("action1方法被执行了,接收到参数["+ event +"]");
}
@Subscribe
public void action2(final Integer event){
System.out.println("action2方法被执行了,接收到参数["+ event +"]");
}
}
定义一个生产者
public class SimpleEventBusExample {
public static void main(String[] args) {
EventBus eventBus = new EventBus();
eventBus.register(new SimpleListener());
eventBus.post("测试");
eventBus.post("1");
}
}
结果
action1方法被执行了,接收到参数[测试]
action1方法被执行了,接收到参数[1]
例2:如果子类和父类都有监听方法,指定子类监听时,父类的监听方法也会被执行
定义一个子类和一个父类,都各自有一个监听方法
//父类
public abstract class AbstractListener {
@Subscribe
public void action(String event){
System.out.println("抽象类action方法被执行了,接收到参数["+ event +"]");
}
}
//子类
public class CreateListener extends AbstractListener{
@Subscribe
public void actionSon(String event){
System.out.println("子类actionSon方法被执行了,接收到参数["+ event +"]");
}
}
定义一个生产者
public class SimpleEventBusExample {
public static void main(String[] args) {
EventBus eventBus = new EventBus();
eventBus.register(new CreateListener());
eventBus.post("测试");
}
}
结果:
子类actionSon方法被执行了,接收到参数[测试]
抽象类action方法被执行了,接收到参数[测试]