在使用ApplicationEvent和Listener快速实现业务解耦中提到了用Spring提供的观察者设计模式完成系统内部逻辑解耦。本文将介绍Google-Guava中的一种消息发布-订阅类库——EventBus。
EventBus 是Google.Guava提供的消息发布-订阅类库,它实现了观察者设计模式,消息通知负责人通过EventBus去注册/注销观察者,最后由消息通知负责人给观察者发布消息。
前提:在pom.xml中引入guava包

   <dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>27.0-jre</version></dependency>

新建类:
相当于注册中心:注册执行都是通过这个类:


import com.google.common.eventbus.EventBus;public class EventBusCenter {private static EventBus eventBus = new EventBus();private EventBusCenter() {}public static EventBus getInstance() {return eventBus;}public static void register(Object obj) {eventBus.register(obj);}public static void unregister(Object obj) {eventBus.unregister(obj);}public static void post(Object obj) {eventBus.post(obj);}}

兴建两个观察者:

import com.google.common.eventbus.Subscribe;public class DataObserver1 {  /** * 只有通过@Subscribe注解的方法才会被注册进EventBus * 而且方法有且只能有1个参数 * * @param msg */  @Subscribepublic void func(String msg) {System.out.println("String msg: " + msg);  }  }

import com.google.common.eventbus.Subscribe;/*** Created by zhangzh on 2017/1/10. */
public class DataObserver2 {  /** * post() 不支持自动装箱功能,只能使用Integer,不能使用int,否则handlersByType的Class会是int而不是Intege * 而传入的int msg参数在post(int msg)的时候会被包装成Integer,导致无法匹配到 */  @Subscribepublic void func(Integer msg) {  System.out.println("Integer msg: " + msg);  }
}

可以看到通过 @Subscribe注解只能有一个参数,如果是两个参数就会报错,只能有一个参数:

Exception in thread "main" com.google.common.util.concurrent.UncheckedExecutionException: java.lang.IllegalArgumentException: Method public void com.study.eventbus.DataObserver1.func(java.lang.String,java.lang.String) has @Subscribe annotation but has 2 parameters.Subscriber methods must have exactly 1 parameter.at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2050)at com.google.common.cache.LocalCache.get(LocalCache.java:3952)at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3974)at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4958)at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:4964)at com.google.common.eventbus.SubscriberRegistry.getAnnotatedMethods(SubscriberRegistry.java:173)at com.google.common.eventbus.SubscriberRegistry.findAllSubscribers(SubscriberRegistry.java:164)at com.google.common.eventbus.SubscriberRegistry.register(SubscriberRegistry.java:74)at com.google.common.eventbus.EventBus.register(EventBus.java:186)at com.study.eventbus.EventBusCenter.register(EventBusCenter.java:21)at com.study.eventbus.Test.main(Test.java:13)
Caused by: java.lang.IllegalArgumentException: Method public void com.study.eventbus.DataObserver1.func(java.lang.String,java.lang.String) has @Subscribe annotation but has 2 parameters.Subscriber methods must have exactly 1 parameter.at com.google.common.base.Preconditions.checkArgument(Preconditions.java:412)at com.google.common.eventbus.SubscriberRegistry.getAnnotatedMethodsNotCached(SubscriberRegistry.java:184)at com.google.common.eventbus.SubscriberRegistry.access$000(SubscriberRegistry.java:54)at com.google.common.eventbus.SubscriberRegistry$1.load(SubscriberRegistry.java:154)at com.google.common.eventbus.SubscriberRegistry$1.load(SubscriberRegistry.java:151)at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3528)at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2277)at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2154)at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2044)... 10 more

然后编写测试类:

/** * Created by zhangzh on 2017/1/10. */
public class Test {  public static void main(String[] args) throws InterruptedException {  DataObserver1 observer1 = new DataObserver1();  DataObserver2 observer2 = new DataObserver2();  EventBusCenter.register(observer1);  EventBusCenter.register(observer2);  System.out.println("============   start  ====================");  // 只有注册的参数类型为String的方法会被调用  EventBusCenter.post("post string method");  EventBusCenter.post(123);  System.out.println("============ after unregister ============");  // 注销observer2  EventBusCenter.unregister(observer2);  EventBusCenter.post("post string method");  EventBusCenter.post(123);  System.out.println("============    end           =============");  }
}


总结:
EventBus的使用注意问题:

  • 代码可读性很差,项目中使用的时候,从post的地方,查询handle使用,都是使用ide的搜索服务,问题很难定位,不如普通的接口调用方便查询;
  • 由于EventBus是将消息队列放入到内存中的,listener消费这个消息队列,故系统重启之后,保存或者堆积在队列中的消息丢失。

作者:jackcooper
链接:https://www.jianshu.com/p/93486a604c34
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

EventBus使用详解的相关推荐

  1. EventBus使用详解(二)——EventBus使用进阶

    前言:这段时间感觉自己也有点懒了,真是内心有点自责呢,除了工作,也没做点什么,EventBus也是一周前总结出来的,只能以写博客为名来弥补内心的罪恶感了,集合同事们做的项目,虽然上周开动了,但总感觉大 ...

  2. EventBus使用详解 1

    前言:EventBus出来已经有一段时间了,github上面也有很多开源项目中使用了EventBus.所以抽空学习顺便整理了一下.目前EventBus最新版本是3.0,所以本文是基于EventBus3 ...

  3. Android | EventBus使用详解

    前言 EventBus是一种用于Android的发布/订阅事件总线.它有很多优点:简化应用组件间的通信:解耦事件的发送者和接收者:避免复杂和容易出错的依赖和生命周期的问题:很快,专门为高性能优化过等等 ...

  4. android eventbus使用,Android EventBus使用详解(一)

    前言 EventBus是一种用于Android的发布/订阅事件总线.它有很多优点:简化应用组件间的通信:解耦事件的发送者和接收者:避免复杂和容易出错的依赖和生命周期的问题:很快,专门为高性能优化过等等 ...

  5. Android之EventBus使用详解

    一.概述 当Android项目越来越庞大的时候,应用的各个部件之间的通信变得越来越复杂,例如:当某一条件发生时,应用中有几个部件对这个消息感兴趣,那么我们通常采用的就是观察者模式,使用观察者模式有一个 ...

  6. EventBus使用详解

    EventBus是一个基于发布者/订阅者模式的事件总线框架. 发布者/订阅者模式,也就是观察者模式(定义了对象之间的一种一对多的依赖关系,当一个对象状态发生改变时,它的所有依赖者都会收到通知并自动更新 ...

  7. 【Android开发】greenrobot三大开源利器详解(一)——EventBus

    一.greenrobot介绍 greenrobot相关信息较少,可以确信是一个开源组织.官网:http://greenrobot.org/. greenrobot主要开发并维护了3个Android开源 ...

  8. Android消息传递之EventBus 3.0使用详解

    前言: 前面两篇不仅学习了子线程与UI主线程之间的通信方式,也学习了如何实现组件之间通信,基于前面的知识我们今天来分析一下EventBus是如何管理事件总线的,EventBus到底是不是最佳方案?学习 ...

  9. EventBus:基本使用详解

    一.简介 EventBus项目:https://github.com/greenrobot/EventBus EventBus 3.0.0 API:http://greenrobot.org/file ...

最新文章

  1. Excel弱爆了!这个工具30分钟完成了我一天的工作量,零基础、文科生也能学!...
  2. 云上主机SSH秘钥对连接linux注意事项
  3. cnn图像进行预测_CNN方法:使用聚合物图像预测其玻璃化转变温度
  4. java中$和 的区别详解_Mybatis之#{}与${}的区别使用详解
  5. 汇编语言——第2次上机实验
  6. 大津二值化算法 ( Otsu's binarization ) 自动确定二值化图像时的阈值
  7. 为什么rstudio打开是空白的_既然大家都说装了win10,就不用鲁大师监测显卡温度,为什么呢?...
  8. sap未分摊差异怎么处理_聊一聊,临时外包员工差异化薪酬要怎么处理
  9. Linux命令大全.pdf
  10. 国家社科基金项目清单、申报书填写指南和课题申报书模板
  11. pscp新机器提示Store key in cache? 重装后提示Update cached key?的解决方案
  12. Gym 101572 K.Kayaking Trip【二分+贪心】
  13. linux-centos7-重置密码(rd.break 方法)
  14. 超火的微信小说小程序源码-自带采集带安装教程
  15. OpenGL LookAt函数理解
  16. Python爬虫爬取微信朋友圈的方法,感兴趣的朋友可以了解下
  17. 一文搞懂 Web Worker(原理到实践)
  18. 增强现实入门实战,使用ArUco标记实现增强现实
  19. 【赛鱼电竞】用王者荣耀免费改名卡改名和王者荣耀怎么修改昵称及王者荣耀改名卡免费修改昵称方法教程
  20. Using a password on the command line interface can be insecure.

热门文章

  1. 深度剖析ConcurrentHashMap(转)
  2. GStreamer基础教程02——GStreamer概念
  3. 什么是面向对象编程(Java)
  4. [计算机网络] --- RSTP运行原理及配置
  5. 凸优化笔记6(共轭梯度法)
  6. Java Long类型对比
  7. 《Java Web程序设计基础教程》前言
  8. Mysql定时任务,最简单例子
  9. 华南师大计算机转专业,广西师范大学计算机科学与信息工程学院/软件学院转专业管理规定(试行)...
  10. Sobel和Roberts算子的推导过程