有三个角色:java
一、事件源:事件产生的地方,能够是一个类的任何方法,它主要职责是维护了一系列的监听器的集合,定义在什么地方发出监听动做spring
二、事件:一个具体的动做,事件源能够定义出多种事件,如改变name值的事件,改变id值的事件app
三、事件监听器:它是监听到特定的事件后要做出的动做,如接受到name改变的事件后发记录下name改变的值框架
事件源中维护了一个listener的集合,这而且设定了setName setId的方法中去调用监听器less
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"); } }
事件:主要是绑定事件源传递给listeneride
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(); } }
事件监听器:当监听源触发事件后能够回调到监听器this
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等等spa
Spring中具体的应供实例以下:代理
如图所示,SpringApplication这个类在启动的时候,须要作框架事件的分发,在初始化的每步骤中都有特定的事件发布给监听器,code
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不要混淆了,我的感受这个名字起的有点不太好)