guava学习--事件驱动模型
转载:http://www.cnblogs.com/whitewolf/p/4132840.html
http://www.cnblogs.com/peida/p/EventBus.html
更好的文章:https://my.oschina.net/realfighter/blog/406342
Guava在guava-libraries中为我们提供了事件总线EventBus库,它是事件发布订阅模式的实现,让我们能在领域驱动设计(DDD)中以事件的弱引用本质对我们的模块和领域边界很好的解耦设计。
不再多的废话,直奔Guava EventBus主题。首先Guava为我们提供了同步事件EventBus和异步实现AsyncEventBus两个事件总线,他们都不是单例的,官方理由是并不想我们我们的使用方式。当然如果我们想其为单例,我们可以很容易封装它,一个单例模式保证只创建一个实例就对了。
下面将以EventBus为例,AsyncEventBus使用方式与其一致的。
1.同步事件EventBus
订阅
首先EventBus为我们提供了register方法来订阅事件,Guava在这里的实现很友好,我们不需要实现任何的额外接口或者base类,只需要在订阅方法上标注上@Subscribe和保证只有一个输入参数的方法就可以搞定。
发布
对于事件源,则可以通过post方法发布事件。 正在这里对于Guava对于事件的发布,是依据上例中订阅方法的方法参数类型决定的,换而言之就是post传入的类型和其基类类型可以收到此事件。
建议对于每类事件封装一个特定的事件类型是必要的。
消息封装类:
public class TestEvent {
private final int message;
public TestEvent(int message) {
this.message = message;
System.out.println("event message:"+message);
}
public int getMessage() {
return message;
}
}
消息接收类:
public class EventListener {
public int lastMessage = 0;
@Subscribe
public void listen(TestEvent event) {
lastMessage = event.getMessage();
System.out.println("Message:"+lastMessage);
}
public int getLastMessage() {
return lastMessage;
}
}
测试类及输出结果:
public class TestEventBus {
@Test
public void testReceiveEvent() throws Exception {
EventBus eventBus = new EventBus("test");
EventListener listener = new EventListener();
eventBus.register(listener);
eventBus.post(new TestEvent(200));
eventBus.post(new TestEvent(300));
eventBus.post(new TestEvent(400));
System.out.println("LastMessage:"+listener.getLastMessage());
;
}
}
//输出信息
event message:200
Message:200
event message:300
Message:300
event message:400
Message:400
LastMessage:400
MultiListener的使用:
只需要在要订阅消息的方法上加上@Subscribe注解即可实现对多个消息的订阅,代码如下:
public class MultipleListener {
public Integer lastInteger;
public Long lastLong;
@Subscribe
public void listenInteger(Integer event) {
lastInteger = event;
System.out.println("event Integer:"+lastInteger);
}
@Subscribe
public void listenLong(Long event) {
lastLong = event;
System.out.println("event Long:"+lastLong);
}
public Integer getLastInteger() {
return lastInteger;
}
public Long getLastLong() {
return lastLong;
}
}
测试类:
public class TestMultipleEvents {
@Test
public void testMultipleEvents() throws Exception {
EventBus eventBus = new EventBus("test");
MultipleListener multiListener = new MultipleListener();
eventBus.register(multiListener);
eventBus.post(new Integer(100));
eventBus.post(new Integer(200));
eventBus.post(new Integer(300));
eventBus.post(new Long(800));
eventBus.post(new Long(800990));
eventBus.post(new Long(800882934));
System.out.println("LastInteger:"+multiListener.getLastInteger());
System.out.println("LastLong:"+multiListener.getLastLong());
}
}
//输出信息
event Integer:100
event Integer:200
event Integer:300
event Long:800
event Long:800990
event Long:800882934
LastInteger:300
LastLong:800882934
在这里有 Integer,Long,与它们基类Number。我们发送一个整数数据的时候,或者Integer和Number的方法接收,而Long类型则Long类型和Number类型接受。
可以使用此功能来创建更通用的监听器监听一个广泛的事件和更详细的具体的特殊的事件。(是类似的意思,看懂即可)。
Dead Event:
如果EventBus发送的消息都不是订阅者关心的称之为Dead Event。实例如下:
public class DeadEventListener {
boolean notDelivered = false;
@Subscribe
public void listen(DeadEvent event) {
notDelivered = true;
}
public boolean isNotDelivered() {
return notDelivered;
}
}
测试类:
public class TestDeadEventListeners {
@Test
public void testDeadEventListeners() throws Exception {
EventBus eventBus = new EventBus("test");
DeadEventListener deadEventListener = new DeadEventListener();
eventBus.register(deadEventListener);
eventBus.post(new TestEvent(200));
eventBus.post(new TestEvent(300));
System.out.println("deadEvent:"+deadEventListener.isNotDelivered());
}
}
//输出信息
event message:200
event message:300
deadEvent:true
说明:如果没有消息订阅者监听消息, EventBus将发送DeadEvent消息,这时我们可以通过log的方式来记录这种状态。
更好的文章:https://my.oschina.net/realfighter/blog/406342
guava学习--事件驱动模型的更多相关文章
- Guava ---- EventBus事件驱动模型
在软件开发过程中, 难免有信息的共享或者对象间的协作. 怎样让对象间信息共享高效, 而且耦合性低. 这是一个难题. 而耦合性高将带来编码改动牵一发而动全身的连锁效应. Spring的风靡正是由于攻克了 ...
- Java学习疑惑(8)----可视化编程, 对Java中事件驱动模型的理解
我们编写程序就是为了方便用户使用, 我觉得UI设计的核心就是简洁, 操作过于繁琐的程序让很大一部分用户敬而远之. 即使功能强大, 但是人们更愿意使用易于操作的软件. 近年流行起来的操作手势和逐渐趋于成 ...
- salesforce lightning零基础学习(二) lightning 知识简单介绍----lightning事件驱动模型
看此篇博客前或者后,看一下trailhead可以加深印象以及理解的更好:https://trailhead.salesforce.com/modules/lex_dev_lc_basics 做过cla ...
- python学习之-- 事件驱动模型
目前主流的网络驱动模型:事件驱动模型 事件驱动模型:也属于生产者/消费者结构,通过一个队列,保存生产者触发的事件,队列另一头是一个循环从队列里不断的提取事件.大致流程如下:1:首先生成一个事件消息队列 ...
- (六)观察者模式详解(包含观察者模式JDK的漏洞以及事件驱动模型)
作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 本章我们讨论一个除前面的单例 ...
- 设计模式之 观察者模式详解(包含观察者模式JDK的漏洞以及事件驱动模型)
作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 本章我们讨论一个除前面的单例 ...
- 事件驱动模型实例详解(Java篇)
或许每个软件从业者都有从学习控制台应用程序到学习可视化编程的转变过程,控制台应用程序的优点在于可以方便的练习某个语言的语法和开发习惯(如.net和java),而可视化编程的学习又可以非常方便开发出各类 ...
- 35.python之事件驱动模型
转载:https://www.cnblogs.com/yuanchenqi/articles/5722574.html 事件驱动模型 上节的问题: 协程:遇到IO操作就切换. 但什么时候切回去呢?怎么 ...
- Guava学习笔记目录
Guava 是一个 Google 的基于java1.6的类库集合的扩展项目,包括 collections, caching, primitives support, concurrency libra ...
随机推荐
- WebViewClient shouldOverrideUrlLoading 常见错误用法
需求描述 在使用 WebView 的项目中,一个常见的需求是将页面内的链接跳转限制在 WebView 内,而不是使用外部浏览器打开,但 WebView 的默认行为是将链接点击事件作为 Intent 发 ...
- 使用 robotframework 自动化测试系列 二 -----环境搭建
环境搭建是测试人员基础,本质都是不难的,按照流程和步骤一步步做,遇到问题不要担心,解决的问题越多,你理解的也就越多. 1. 安装python环境,python现在有python2 和python3.由 ...
- struts2-通配符映射(基本没啥卵用)和动态调用
通配符 使用*代表任意字符 一般在action的name中使用*,并可以使用多个 可以使用{通配符的序号}引用对应的通配符所代表的值,序号从1开始 {0}代表整个URI 匹配规则 首先完全匹配,没有完 ...
- spring1冲刺感想与总结
感想与体会: 通过团队合作的第一个sprint,我们知道如何在团队合作中做好自己,还有与队友不合时,如何和平处理问题.产品负责人是一个重要的的角色,他负责任务的安排,处理合作中意见不统一的问题.通过这 ...
- jQ HTML之捕获 设置 元素添加与删除
捕获 设置修改 添加元素 删除元素
- js中获取当前时间
var d = new Date();var date = d.getFullYear() + "年" +(d.getMonth() + 1) + "月" + ...
- SQL系统视图表
SQL系统视图表 )) + '学年' + ss.Name AS listtext, sc.SchoolId FROM dbo.SchoolCalendar AS sc INNER JOIN dbo.S ...
- JQ 全选、全不选
$(document).ready(function() { $("#isalldebt").click(function() { if ($(this).attr("c ...
- React高级特性
目录: 容器组件 JSX可展开属性 动画 : CSS3 Transition 默认属性 复用代码:mixin 容器组件 React元素也可以包含其他的子元素,这意味着响应的React组件是一个 容器组 ...
- ALLOCATE语句分配FORTRAN动态数组方法(转自http://blog.csdn.net/zhuxianjianqi/article/details/8067174)
数组的动态分配 a) 可分配数组 数组可以是静态的也可以是动态的.如果数组是静态的,则在编译时就被分配了固定的储存空间,并且直到程序退出时才被释放.程序运行时静态数组的大小不能改变.静态数组的缺 ...