在路上

路上有惊慌,路上有理想

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  28 Posts :: 1 Stories :: 10 Comments :: 0 Trackbacks

写在前面的话:spring的监听事件模型应该是观察者模式。本人项目里的应用在process方法按日期同步某个库的数据,在方法最后publish一个event事件,这个事件用于后续同步过来的数据处理。事件处理采用了spring的监听模型.这样可以做到process方法与event可以异步分离执行。(注:这个事件模型缺省使用SyncTaskExecutor来执行listener的注册event,所有该listener注册的event事件为同步执行的)。

当然,spring的这个机制还有很多应用的场景,就不一一列举了。

ApplicationEvent

事件抽象类,里面只有一个构造函数和一个timestamp。

ApplicationListener

监听接口,里面只有一个onApplicationEvent方法。需要用户自己编写ApplicationListener的实现。

ApplicationContext

spring上下文,其publishEvent方法用于通知监听器(ApplicationListener的实现)注册event时间.

publishEvent

void publishEvent(ApplicationEvent event)

Notify all listeners registered with this application of an application event.

源码解读:
1.作为ApplicationContext的实现AbstractApplicationContext.java的成员变量applicationListeners,是一个ArrayList,保存了所有的ApplicationListener
2.利用ApplicationEventMulticaster接口里的方法来完成注册监听addApplicationListener,移除监听removeApplicationListener,removeAllListeners,以及通知监听注册事件event:multicastEvent(ApplicationEvent event);
上面说到的publishEvent方法即使用了multicastEvent方法

SimpleApplicationEventMultucaster作为ApplicationEventMulticaster的一个实现,提供了multicastEvent的实现代码,其实就是迭代所有的监听器,用SyncTaskExecutor同步执行listener的onApplicationEvent

public void multicastEvent(final ApplicationEvent event) {

for (Iterator it = getApplicationListeners().iterator(); it

.hasNext();) {

final ApplicationListener listener = (ApplicationListener) it

.next();

getTaskExecutor().execute(new Runnable() {

public void run() {

listener.onApplicationEvent(event);
}
});
}

3.注意事项:自己编写ApplicationListener的实现时,要注意不同的监听器处理不同的事件(复写onApplicationEvent)。原因就是multicastEvent的执行原理。它是迭代执行所有的监听器onApplicationEvent

这里是ApplicationEventMulticaster的类分布图



abstract public class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster(Code)(Java Doc)
public interface ApplicationEventMulticaster (Code)(Java Doc)

public class SimpleApplicationEventMulticaster extends

这里是ApplicationContext的类分布图
public class DefaultResourceLoader implements ResourceLoader(Code)(Java Doc)
public interface ResourceLoader (Code)(Java Doc)

abstract public class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext,DisposableBean(Code)(Java Doc)
public interface ConfigurableApplicationContext extends ApplicationContext,Lifecycle(Code)(Java Doc)
public interface DisposableBean (Code)(Java Doc)

public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry(Code)(Java Doc)
public interface BeanDefinitionRegistry (Code)(Java Doc)

abstract public class AbstractRefreshableApplicationContext extends
下面是spring自身的事件应用
1) ContextRefreshedEvent:当ApplicationContext初始化或者刷新时触发该事件。
2) ContextClosedEvent:当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。
3) RequestHandleEvent:在Web应用中,当一个http请求(request)结束触发该事件。
4) ContestStartedEvent:当容器调用ConfigurableApplicationContext的Start()方法开始/重新开始容器时触发该事件。
5) ContestStopedEvent:当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。

posted on 2010-09-01 10:41 阮步兵 阅读(5338) 评论(6)  编辑  收藏 所属分类: OpenSource

Feedback

# re: Spring之事件监听 2010-09-01 10:54 @joe
都有啥有用场景?  回复  更多评论
  

# re: Spring之事件监听[未登录] 2010-09-01 11:30 毛掌柜
@@joe
比如在facebook中,一般上传一张照片都会对于一个activity的产生,这个时候就可以用这个东西。
记得SimpleApplicationEventMultucaster的listener都是同步执行,需要再瞧瞧代码。。。  回复  更多评论
  

# re: Spring之事件监听 2010-09-01 11:41 阮步兵
getTaskExecutor().execute(new Runnable() {

public void run() {

listener.onApplicationEvent(event);
}
});
以上是SimpleApplicationEventMultucaster的部分代码,它选择的是new Runnable来执行listener  回复  更多评论
  

# re: Spring之事件监听 2010-09-01 11:43 阮步兵
@@joe
一个任务里面,比如包括上传文件和数据处理,如果文件不必立刻相应给客户,可以通过事件监听的方式来实现。另外,业务流程中有邮件处理以及日志处理的,都可以在主流程结束后执行,可以选择事件监听方式处理。  回复  更多评论
  

# re: Spring之事件监听[未登录] 2010-09-01 13:20 毛掌柜
@阮步兵
看了下Spring 3的代码,确实是同步的。
可以看下SyncTaskExecutor的代码。  回复  更多评论
  

# re: Spring之事件监听 2010-09-01 21:24 阮步兵
SimpleApplicationEventMultucaster确实采用的是SyncTaskExecutor同步executor,也就是说SimpleApplicationEventMultucaster的listener都是同步执行。当一个listener有多个事件需要处理时,同步执行。  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: