Guava - EventBus

EventBus

介绍

EventBusGuava包里的一个辅助类, 用于实现消息总线模式.

生产事件的叫做Provider, 消费事件的叫做Subscriber, 他们之间通过事件类型产生关联.

 

核心类介绍

EventBus

核心类同步的EventBus, subscriber会和provider在同一个线程上执行. 每个EventBus有一个id标识, 仅做标识展示用, 没有其他作用. 对异常的处理仅仅是log, 因此subscriber自己要做好异常处理, 可以自定义异常处理器.

 

SubscriberRegistry

Subscriber的注册中心, 登记所有subscriber, 以及维护每种event类型可以被哪些subscriber处理.

  • 内部维护了ConcurrentMap<Class<?>, CopyOnWriteArraySet<Subscriber>>, 很容易看出是所有Event类型及其对应的Subscriber. 使用了 ConcurrentHashMap 和 CopyOnWriteArraySet 来保证动态添加订阅关系时的安全性.

  • 注册一个Subscriber时, 会遍历它的所有父类搜索有注解的接口.

  • 当搜索每个event类型可以被哪些subscriber处理时, 他会遍历event类型的所有父类型, 将所有涉及到的Subscriber都加在一起.

 

@Subscribe

在你的Subscriber类上标记你的方法, 就可以注册为回调.

 

Dispatcher

负责调用Subscriber, 控制调用顺序.

有下面几种实现, 但通常你无法选择, 因为没有暴露相关接口.

  • PerThreadQueueDispatcher: 可以保证由同一个线程发出的所有事件有序地被subscriber处理, 用一个queuehold住所有event, 然后消费; 这里的实现有点意思, 似乎是为了广度优先地处理一个线程发出的所有event; 可以想象一下用的Executor是directExecutor, 然后在subscriber里(处于同一个线程)又发出了event, 那么这时候这些event会等到当前event处理完才被处理

  • ImmediateDispatcher: 立即处理, 深度优先, 但目前并没有被代码用到, 用于可见性也无法用到它

  • LagacyAsyncDispatcher: 异步dispatch, 但为什么是Lagacy??? 不推荐了吗?

    • 同一个线程发出的多个消息的投递顺序不能保证, 因为是放入线程池执行的, 后放的可能比先放的跑

    • 去看它的代码, 很好理解, 就是将每个subscriber调用event的这个动作完全打散

 

Subscriber

负责调用被注解的方法, 如果订阅的方法被AllowConcurrentEvents注解标记了, 则认为该方法是线程安全的, 可以被并发调用. 否则会在调用目标方法时synchronized 关键字锁住当前Subscriber以保证只有一个线程在调用.

 

AsyncEventBus

异步的EventBus, 仅仅只是EventBus的参数定制版.

 

实现里的一些优化点

  • 拼接迭代器, 而不是返回全部元素组成的List, 这样对内存很友好

  • 获取事件类型的所有父类

 

例子

public class EventBusTest {
    @Test
    public void test_sync() {
        // 采用默认配置
        final EventBus b = new EventBus();
        final Subscriber subscriber = new Subscriber();
        b.register(subscriber);

        // 事件类型是 String
        // 关联的Subscriber会在post方法会在当前线程上执行
        b.post("aa");

        assertThat(subscriber.received).isTrue();

        subscriber.received = false;
        b.post(1);
        assertThat(subscriber.received).isTrue();
    }

    public static class Subscriber {
        private boolean received;

        @AllowConcurrentEvents
        @Subscribe
        public void onEvent(String str) {
            System.out.println("String Event " + str);
            received = true;
        }

        @AllowConcurrentEvents
        @Subscribe
        public void onEvent(Integer integer) {
            System.out.println("Integer Event " + integer);
            received = true;
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值