Guava EventBus 使用

Guava EventBus 使用

EventBus 是 Google Guava 提供的消息发布-订阅类库,是设计模式中的观察者模式(生产/消费者编程模型)的优雅实现,消息通知负责人通过 EventBus 去注册/注销观察者,最后由消息通知负责人给观察者发布消息。
对于事件监听和发布订阅模式,EventBus 是一个非常优雅和简单解决方案,我们不用创建复杂的类和接口层次结构。

基本用法

创建事件监听器-Listener

我们只需要在指定的方法上加上 @Subscribe 注解就可以使其变成一个 Listener,这样便能订阅消息了。

/**
 * SimpleListener 监听器
 */
public class SimpleListener {

    /**
     * 一个简单的 Listener 方法,监听 String 类型的消息
     */
    @Subscribe
    public void handle(String event){
      System.out.println("String message: " + event);
    }
}

创建 EventBus 推送消息

创建 EventBus 事件总线,注册事件监听器,并推送消息。

public class SimpleEventBusMain {

    public static void main(String[] args) {

        final EventBus eventBus = new EventBus();

        // 注册事件监听器
        eventBus.register(new SimpleListener());

        // 向订阅者发送消息
        eventBus.post("Hello EventBus");
    }
}

输出结果

String message: Hello EventBus

多事件类型的监听

只需要在要订阅消息的方法上加上 @Subscribe 注解就可以实现对多个不同消息的监听。并且, EventBus 会根据方法参数类型的不同,分别向不同的订阅者 Subscribe 推送不同的消息。参数类型不同,订阅者就不同。

创建 EventBus

/**
 * JobEventBusCenter
 */
public final class JobEventBusCenter {

    private static class JobEventBus {
        private static final EventBus EVENT_BUS = new EventBus();
    }

    public static void register(JobEventListener<?> listener) {
        JobEventBus.EVENT_BUS.register(listener);
    }

    public static void post(JobEvent<?> event) {
        JobEventBus.EVENT_BUS.post(event);
    }

}

创建不同的消息事件

  • 抽象 JobEvent 类
/**
 * JobEvent
 */
public abstract class JobEvent<T> extends EventObject {

    public JobEvent(T source) {
        super(source);
    }

    @Override
    public T getSource() {
        return (T) super.getSource();
    }
}
  • JobEventString 类,String 类型的消息事件
/**
 * String 类型的消息对象
 */
public class JobEventString extends JobEvent<String> {

    public JobEventString(String source) {
        super(source);
    }

    @Override
    public String getSource() {
        return super.getSource();
    }
}
  • JobEventInteger 类,Integer 类型的消息事件
/**
 * Integer 类型的消息对象
 */
public class JobEventInteger extends JobEvent<Integer> {

    public JobEventInteger(Integer source) {
        super(source);
    }

    @Override
    public Integer getSource() {
        return super.getSource();
    }
}

创建事件监听器

  • JobEventListener 接口
/**
 * 事件监听器接口
 */
public interface JobEventListener<T> {

    void handle(T event);
}
  • JobEventStringListener 类,用于监听 String 类型的消息
/**
 * JobEventStringListener
 */
public class JobEventStringListener implements JobEventListener<JobEventString> {

    @Override
    @Subscribe
    public void handle(JobEventString event) {
        String source = event.getSource();

        System.out.println("String message: " + source);
    }
}
  • JobEventIntegerListener 类,用于监听 Integer 类型的消息
/**
 * JobEventIntegerListener
 */
public class JobEventIntegerListener implements JobEventListener<JobEventInteger> {

    @Override
    @Subscribe
    public void handle(JobEventInteger event) {
        Integer source = event.getSource();

        System.out.println("Integer message: " + source);
    }
}

创建 EventBus

  • JobEventBusCenter 类,封装 EventBus 的功能
/**
 * JobEventBusCenter
 */
public final class JobEventBusCenter {

    private static class JobEventBus {
        private static final EventBus EVENT_BUS = new EventBus();
    }

    public static void register(JobEventListener<?> listener) {
        JobEventBus.EVENT_BUS.register(listener);
    }

    public static void post(JobEvent<?> event) {
        JobEventBus.EVENT_BUS.post(event);
    }

}
  • EventBusMain 类
/**
 * EventBusMain
 */
public class EventBusMain {

    public static void main(String[] args) {

        JobEventIntegerListener integerListener = new JobEventIntegerListener();
        JobEventStringListener stringListener = new JobEventStringListener();
        // 注册事件监听器
        JobEventBusCenter.register(integerListener);
        JobEventBusCenter.register(stringListener);
        // 发送事件
        JobEventBusCenter.post(new JobEventString("hello eventBus"));
        JobEventBusCenter.post(new JobEventInteger(123));
    }
}

输出结果

String message: hello eventBus
Integer message: 123

继承关系的 Event

如果 Listener A 监听 Event A, 而 Event A 有一个子类 Event B, 此时 Listener A 将同时接收 Event A 和 B 消息。

  • 具有继承关系的两个类
/**
 * Animal
 */
public class Animal {

    private String name;

    public Animal(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

/**
 * Dog
 */
public class Dog extends Animal {

    public Dog(String name) {
        super(name);
    }
}
  • 监听器
/**
 * AnimalListener
 */
public class AnimalListener {

    @Subscribe
    public void handle(Animal animal) {
        System.out.println("Animal name: " + animal.getName());
    }

    @Subscribe
    public void handle(Dog dog) {
        System.out.println("Dog name: " + dog.getName());
    }
}
  • 创建 EventBus
public class EventBusMain {

    public static void main(String[] args) {

        final EventBus eventBus = new EventBus();

        // 注册事件监听器
        eventBus.register(new AnimalListener());

        // 向订阅者发送消息
        eventBus.post(new Dog("dingding"));
    }
}

Dog name: dingding
Animal name: dingding

注意

  1. 使用 EventBus 时,监听方法的参数有且只能有一个,必须是引用类型,不能是基本数据类型,如:int 要换成 Integer,long 要缓存 Long 等等;
  2. 由于 EventBus 是将消息队列放入到内存中的,由 Listener 消费这个消息队列,故系统重启之后,保存或者堆积在队列中的消息丢失。

参考

Guide to Guava’s EventBus:https://www.baeldung.com/guava-eventbus#overview

发布了89 篇原创文章 · 获赞 79 · 访问量 17万+

猜你喜欢

转载自blog.csdn.net/oschina_41790905/article/details/104041949