文档章节

事件监听模式

zswitos
 zswitos
发布于 2015/04/27 16:12
字数 886
阅读 11
收藏 0
点赞 0
评论 0

Design patterns

 

1、事件监听模式

 

有三个角色:

    1、事件源:事件产生的地方,可以是一个类的任何方法,它主要职责是维护了一系列的监听器的集合,定义在什么地方发出监听动作

    2、事件:一个具体的动作,事件源可以定义出多种事件,如改变name值的事件,改变id值的事件

    3、事件监听器:它是监听到特定的事件后要作出的动作,如接受到name改变的事件后发记录下name改变的值

 

 

 

 

事件源中维护了一个listener的集合,这并且设定了setName setId的方法中去调用监听器

 

package com.springapp.beans.lisentner; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * Created by zsw on 15-4-27. * 事件源 */ public class MyResourceObj{    private String id;    private String name;    private List<MyListener> listenerList = new ArrayList<MyListener>();    public List<MyListener> getListenerList() {        return listenerList;    }    public void setListenerList(List<MyListener> listenerList) {        this.listenerList = listenerList;    }    public void registeListener(MyListener listener){        this.listenerList.add(listener);    }    public void rmListener(MyListener listener){        this.listenerList.remove(listener);    }    public String getId() {        return id;    }    public void setId(String id) {        this.id = id;        notifyAllListeners();
    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;        notifyAllListeners();
    }    private void notifyAllListeners(){//通知监听器执行用户自定义的方法        if(listenerList.size()>0){            Iterator iterator = listenerList.iterator();            while (iterator.hasNext()){                ((MyListener)iterator.next()).fireEvent(new MySetEvent(this));            }        }    }    public static void main(String[] args) {        MyResourceObj obj = new MyResourceObj();        obj.registeListener(new MySetListener());        obj.setName("zsw");    } } 

 

事件:主要是绑定事件源传递给listener

 

package com.springapp.beans.lisentner; 
/**  * Created by zsw on 15-4-27.  */ public class MySetEvent implements MyEvent { 
    public MySetEvent(){} 
    public MySetEvent(Object obj){         this.eventSourceObj = obj;     } 
    private Object eventSourceObj; 
    public Object getEventSourceObj() {         return eventSourceObj;     } 
    public void setEventSourceObj(Object eventSourceObj) {//绑定事件源给Listener         this.eventSourceObj = eventSourceObj;     } 
    @Override     public Object getSource() {         return this.getEventSourceObj();     } } 

 

事件监听器:当监听源触发事件后可以回调到监听器

package com.springapp.beans.lisentner; 
/**  * Created by zsw on 15-4-27.  */ public class MySetListener implements MyListener { 
    @Override     public void fireEvent(MyEvent event) {         if(event.getClass().isAssignableFrom(MySetEvent.class)){             System.err.println("log message : my name or id is change:"                     + "{name is:"+((MyResourceObj) ((MySetEvent) event).getEventSourceObj()).getName() +",id is :"+                     (((MyResourceObj) ((MySetEvent) event).getEventSourceObj()).getId())+"}");         }     } } 

 

 

Spring在在家的applicationContext中设置了好多Aware接口的实现类监听机制,每个都有自己的作用,可以设置ApplicationContext对象,获取生产自己的工厂BeanFactory等等

 

Spring中具体的应供实例如下:

 

 

如图所示,SpringApplication这个类在启动的时候,需要做框架事件的分发,在初始化的每步骤中都有特定的事件发布给监听器,

public ConfigurableApplicationContext run(String... args) {
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		ConfigurableApplicationContext context = null;
		FailureAnalyzers analyzers = null;
		configureHeadlessProperty();
//创建事件发布者
		SpringApplicationRunListeners listeners = getRunListeners(args);
//通过发布者类分发start时刻的事件
		listeners.starting();
		try {
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(
					args);
			ConfigurableEnvironment environment = prepareEnvironment(listeners,
					applicationArguments);
			Banner printedBanner = printBanner(environment);
			context = createApplicationContext();
			analyzers = new FailureAnalyzers(context);
			prepareContext(context, environment, listeners, applicationArguments,
					printedBanner);
			refreshContext(context);
			afterRefresh(context, applicationArguments);
//发布上下文环境初始化完成的事件
			listeners.finished(context, null);
			stopWatch.stop();
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass)
						.logStarted(getApplicationLog(), stopWatch);
			}
			return context;
		}
		catch (Throwable ex) {
			handleRunFailure(context, listeners, analyzers, ex);
			throw new IllegalStateException(ex);
		}
	}

流程图如下

 

Spring把事件源跟时间发布分离了,不集中在事件源里面的去维护代码,代码职责分离,它内部持有一个SpringApplicationRunListerns的实现类,这个类里面持有各种实现类集合,由他去继续分发给他的内部结合的实现类去处理发送事件给监听器

而SpringApplicationRunListerns的实现类(默认 : EventPublishingRunListener)内部持有了 一个事件广播器,真正的事件分发就是又这个事件广播器去实现动作,

SimpleApplicationEventMulticaster,他内部已经持有了初始化好的系统中所以的监听器实现类实例,

注意:监听器的接口是ApplicationListern,而事件广播代理其接口是SpringApplicationRunListerns不要混淆了,个人感觉这个名字起的有点不太好

 

© 著作权归作者所有

共有 人打赏支持
zswitos
粉丝 4
博文 58
码字总数 54950
作品 0
海淀
程序员
IO多路复用之epoll总结

IO多路复用之epoll总结 epoll是在2.6内核中提出的,是之前的select和poll的增强版本。相对于select和poll来说,epoll更加灵活,没有描述符限制。epoll使用一个文件描述符管理多个描述符,将用...

杰思
2017/08/03
0
0
IO多路复用之epoll总结

1、基本知识   epoll是在2.6内核中提出的(mac没有),是之前的select和poll的增强版本。相对于select和poll来说,epoll更加灵活,没有描述符限制。epoll使用一个文件描述符管理多个描述符,...

Lennie002
2015/05/09
0
1
Android 框架学习3:从 EventBus 中学到的精华

关联文章: EventBus 3.0 的特点与如何使用 源码分析 EventBus 3.0 如何实现事件总线 学习的目的是为了超越,经过前面对 EventBus 3.0 的学习,我们已经对它相当熟悉了,现在来总结下,从这个...

u011240877
2017/07/06
0
0
运用java的监听模式封装excel的读取

运用android listener监听模式设计excel的读取 熟悉java开发的人想必不会对监听模式陌生,在android的应用层的设计中,普遍采用这种监听模式(点击事件、Touch事件等) 本人最近研究android...

风过后
2014/06/06
0
3
Curator的三种缓存。

在使用原生的ZooKeeper的时候,是可以使用Watcher对节点进行监听的,但是唯一不方便的是一个Watcher只能生效一次,也就是说每次进行监听回调之后我们需要自己重新的设置监听才能达到永久监听...

Leafage_M
2017/12/07
0
0
linux epoll使用详解

Linux2.6内核中epoll用法详解 引言 epoll是linux2.6内核中才有的机制,其他版本内核中是没有的,是Linux2.6内核引入的多路复用IO的一种方式,用于提高网络IO 性能的方法。在linux网络编程中,...

lichao19881026
2014/05/12
0
0
linux epoll使用详解

Linux2.6内核中epoll用法详解 引言 epoll是linux2.6内核中才有的机制,其他版本内核中是没有的,是Linux2.6内核引入的多路复用IO的一种方式,用于提高网络IO 性能的方法。在linux网络编程中,...

xiaot99
2014/02/07
0
0
服务器两种高效的并发模式

一、并发编程与并发模式 并发编程主要是为了让程序同时执行多个任务,并发编程对计算精密型没有优势,反而由于任务的切换使得效率变低。如果程序是IO精密型的,则由于IO操作远没有CPU的计算速...

翼动动空
2016/09/22
118
0
nodejs学习笔记Stream(流)

什么流 通俗的说就是一种,有起点和终点的字节数据传输手段,把数据从一个地方传到另一个地方。 流(Stream)是一个抽象接口,可读、可写或兼具两者的。并且所有流都是 EventEmitter 的实例。...

韩公子joy
02/02
0
0
浅谈---事件冒泡--事件捕获--Vue2.0中的capture

前言 主要内容 事件捕获 事件冒泡 事件冒泡和事件捕获-图解 W3C标准事件监听 element.addEventListener(event-name, callback, use-capture); 表示在 element 这个对象上面添加一个事件监听器...

青棘
2017/06/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Spring boot中日期的json格式化

Model 在model层中,类的日期属性上面添加如下注解: @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss") 参考 Jackson Date格式化教程...

亚林瓜子
10分钟前
0
0
Eclipse:Failed to load the JNI shared library

1.问题背景: 由于我之前使用jdk1.9学习,当使用Luke的时候发现jdk版本过高,需要向下配置jdk,就向朋友拷了一个安装包。重新配置路径后,便开始报错。 2.问题描述: Failed to load the JNI...

tinder_boy
13分钟前
0
0
少儿学习编程课程是否真的适合七八岁的低龄儿童[图]

少儿学习编程课程是否真的适合七八岁的低龄儿童[图]: 天下熙熙皆为利来,天下攘攘皆为利往。 这几年来,乐高教育机构在国内如同雨后春笋般出现,当然关闭/转手的也很多。从教师角度来看,部...

原创小博客
18分钟前
0
0
ES12-词项查询

1.词项查询介绍 全文查询将在执行之前分析查询字符串,但词项级别查询将按照存储在倒排索引中的词项进行精确操作。这些查询通常用于数字,日期和枚举等结构化数据,而不是全文本字段。 或者,...

贾峰uk
26分钟前
0
0
http状态码与ajax的状态值

ajax状态值 1.1 200 & OK:状态请求成功

litCabbage
29分钟前
0
0
iOS动画效果合集、飞吧企鹅游戏、换肤方案、画板、文字效果等源码

iOS精选源码 动画知识运用及常见动画效果收集 3D卡片拖拽卡片叠加卡片 iFIERO - FLYING PENGUIN 飞吧企鹅SpriteKit游戏(源码) Swift封装的空数据提醒界面EmptyView 沙盒文件浏览与分享调试控...

sunnyaigd
32分钟前
0
0
AngularJS配置.run()块中设置路由事件的监听器以及过滤未经授权的请求

AngularJS中的run方法初始化全局数据,只对全局作用域起作用,如$rootScope.多个控制器之间可以共享数据,如下代码所示: <script type="text/javascript"> var m1 = angular....

孟飞阳
33分钟前
0
0
Java语言学习(十):输入/输出

Java中,I/O操作代表着输入、输出,Java所有的I/O机制都是基于数据流进行输入输出。java.io类包提供了很多的输入输出处理功能方法,大家可以参考下JDK文档中关于I/O的一些处理方法:JDK在线中...

海岸线的曙光
42分钟前
1
0
基于阿里出得ng-Alain搭建后台管理系统

首先跟大家介绍一下ng_Alain(阿里团队出品) ng-alain技术栈基于 Typescript、Angular、g2、@delon 和 ng-zorro-antd,提前了解和学习这些知识会非常有帮助。 ng-alain 脚手架是基于 Angular ...

方宏春
47分钟前
2
0
Spring框架IOC和AOP的实现原理

一、IoC(Inversion of Control) (1). IoC(Inversion of Control)是指容器控制程序对象之间的关系,而不是传统实现中,由程序代码直接操控。控制权由应用代码中转到了外部容器,控制权的转...

HaierBrother
49分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部