事件监听模式
博客专区 > zswitos 的博客 > 博客详情
事件监听模式
zswitos 发表于3年前
事件监听模式
  • 发表于 3年前
  • 阅读 11
  • 收藏 0
  • 点赞 0
  • 评论 0

移动开发云端新模式探索实践 >>>   

摘要: design pattern

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不要混淆了,个人感觉这个名字起的有点不太好

 

  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 4
博文 58
码字总数 54950
×
zswitos
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: