关于事件监听我们需要知道的一些基础知识。

a)事件三要素(who when what):

source     --    事件源
when -- 事件发生时间
message -- 事件主题消息,即希望通过事件传递出去的信息

b)事件模型的构成:

event     --     事件
source -- 事件源
listener -- 事件监听器

c)事件流转过程:

(1)事件源注册监听器 -> (2)事件发生 -> (3)通知监听器 -> (4)监听器处理

那么基于以上背景知识,我们来是实现一个简单的监听器,并测试一下事件监听的完整流程。

根据事件三要素设计出一个简单合理的事件载体:Event

public interface Event extends Serializable {

    Object getSource();

    Date getWhen();

    String getMessage();

    /**
* 事件回调方法
*/
void callback();
}

事件实现:MyEvent

public class MyEvent implements Event {

    private Log log = LogFactory.getLog(getClass());

    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

    private Object source;

    private Date when;

    private String message;

    @Override
public Object getSource() {
return source;
} public void setSource(Object source) {
this.source = source;
} @Override
public Date getWhen() {
return when;
} public void setWhen(Date when) {
this.when = when;
} @Override
public String getMessage() {
return message;
} public void setMessage(String message) {
this.message = message;
} @Override
public void callback() {
log.info(toString());
} @Override
public String toString() {
return "source: " + getSource() + ", message: " + getMessage() + ", when: " + sdf.format(getWhen());
}
}

监听器接口:EventListener

public interface EventListener {

    /**
* 事件触发
* @param event
*/
void handleEvent(Event event);
}

监听器实现:MyListener

public class MyListener implements EventListener {

    @Override
public void handleEvent(Event event) {
event.callback();
}
}

事件源接口:EventSource

public interface EventSource {

    /**
* 增加监听器
* @param listener
*/
void addListener(EventListener listener); /**
* 通知监听器
*/
void notifyListener();
}

编写测试的事件源:MySource

public class MySource implements EventSource {

    private List<EventListener> listeners = new ArrayList<EventListener>();

    private int value;

    @Override
public void addListener(EventListener listener) {
listeners.add(listener);
} @Override
public void notifyListener() {
for (EventListener listener : listeners) {
MyEvent event = new MyEvent();
event.setSource(this);
event.setWhen(new Date());
event.setMessage("setValue " + value);
listener.handleEvent(event);
}
} public int getValue() {
return value;
} public void setValue(int value) {
this.value = value;
notifyListener();
} @Test
public void testEventListener() {
MySource source = new MySource();
source.addListener(new MyListener());
source.setValue(100);
}
}

测试输出:

[INFO]-[Event-callback(50)]: source: com.lichmama.test.listen.MySource@119126ab, message: setValue 100, when: 2018-05-01 02:52:13

*PS:监听器模式和观察者模式看起来很像,不过在事件模型的设置上有些许差别。在观察者模式中并没有Event这个角色,或者说它被合并到Observable角色中了,即整合了事件源与事件。

Java实现一个简单的事件监听器的更多相关文章

  1. 使用lua实现一个简单的事件派发器

    设计一个简单的事件派发器,个人觉得最重要的一点就是如何保证事件派发过程中,添加或删除同类事件,不影响事件迭代顺序和结果,只要解决这一点,其它都好办. 为了使用pairs遍历函数,重写了pairs(lu ...

  2. 使用Java编写一个简单的Web的监控系统cpu利用率,cpu温度,总内存大小

    原文:http://www.jb51.net/article/75002.htm 这篇文章主要介绍了使用Java编写一个简单的Web的监控系统的例子,并且将重要信息转为XML通过网页前端显示,非常之实 ...

  3. 使用 java 实现一个简单的 markdown 语法解析器

    1. 什么是 markdown Markdown 是一种轻量级的「标记语言」,它的优点很多,目前也被越来越多的写作爱好者,撰稿者广泛使用.看到这里请不要被「标记」.「语言」所迷惑,Markdown 的 ...

  4. java:jsp: 一个简单的自定义标签 tld

    java:jsp: 一个简单的自定义标签 tld 请注意,uri都是:http://www.tag.com/mytag,保持统一,要不然报错,不能访问 tld文件 <?xml version=& ...

  5. 使用JAVA写一个简单的日历

    JAVA写一个简单的日历import java.text.DateFormat;import java.text.ParseException;import java.text.SimpleDateF ...

  6. Java实现一个简单的网络爬虫

    Java实现一个简单的网络爬虫 import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileWri ...

  7. Java实现一个简单的文件上传案例

    Java实现一个简单的文件上传案例 实现流程: 1.客户端从硬盘读取文件数据到程序中 2.客户端输出流,写出文件到服务端 3.服务端输出流,读取文件数据到服务端中 4.输出流,写出文件数据到服务器硬盘 ...

  8. 利用java实现一个简单的远程监控程序

    一般的远程监控软件都是用c或者c++等语言开发的,而使用java如何来实现相同的功能呢. 首先我们先介绍一下一个简单的远程监控程序的实现原理. 功能一,远程屏幕监视 (1) 必须要有监控端与被监控端, ...

  9. 【转】转帖并注释:Java中的事件处理机制--事件监听器的四种实现方式

    原文地址:http://blog.sina.com.cn/s/blog_4b650d650100nqws.html Java中四种事件监听器的实现方式分别为: 自身类做为事件监听器 外部类作为事件监听 ...

随机推荐

  1. 推荐算法之E&E

    一.定义 E&E就是探索(explore)和利用(exploit). Exploit:基于已知最好策略,开发利用已知具有较高回报的item(贪婪.短期回报),对于推荐来讲就是用户已经发现的兴趣 ...

  2. Linux下通过md5sum生成MD5文件&校验MD5

    生成md5值 随便找个文件执行:md5sum file_name  即可生成该文件对应md5值. 也可以一次生成多个文件的md5值:md5sum file_name1 file_name2 file_ ...

  3. Django model distinct 的使用方法

    原文: 今天突然有人问起在 django 的 model 里面怎么用 distinct, 对于这种东西,我一向的观点是查看django 的在线文档.于是不加思索的根据在线文档给出了答案,但结果很让人沮 ...

  4. drf之接口规范

    web接口 # 请求工具:postman => https://www.getpostman.com/ # 接口:url链接,通过向链接发生不同的类型请求与数据得到相应的响应数据 # http: ...

  5. SpringBoot,SSM和SSH

    Springboot的概念: 是提供的全新框架,使用来简化Spring的初始搭建和开发过程,使用了特定的方式来进行配置,让开发人员不在需要定义样板化的配置.此框架不需要配置xml,依赖于想MAVEN这 ...

  6. 无法读取例程 &ROUTINE 中配置文件选项 FND_DEVELOPER_MODE

    问题描述:OM>发运>事务处理,进入此界面,FORM出现报错信息:无法读取例程 &ROUTINE 中配置文件选项 FND_DEVELOPER_MODE 解决办法:在系统管理员下,设 ...

  7. jQuery循环之each()

    /** *定义和用法:$(selector).each(function(index,element)) *each()函数会对每个匹配到的元素运行函数(返回false可终止循环). *each()函 ...

  8. 【异常】org.eclipse.jgit.api.errors.TransportException: git@xxx.xxx.xxx/base-config-center.git: channel is not opened.

    一.异常原因 连不上git仓库,可能原因有: 1.)git仓库不存在 2)连接git仓库超时 二.对应的解决办法 1) 创建对应仓库 2) 2.1 换个服务性能更好的部署gitlab 2.2 可以研究 ...

  9. 提高python处理数据的效率方法

    处理大数据的方法有很多,目前我知道就这么多,后面会持续更新: 一.将数据分批次读取 csv格式是常见的数据存储方式,对于我们普通人而言易于读写.此外,在pandas中有pd.read_csv()函数可 ...

  10. 接口自动化--requests库封装

    前言 不管是自动化大佬还是自动化小白,都知道我们用python写接口自动化测试肯定是要用requests库来封装请求类的,下面就简单介绍下requests这个库 安装 一般都是直接采用pip命令安装: ...