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()方法停止容器时触发该事件。

用一个简单的例子来实现spring事件监听的功能

这个例子主要功能是,记录那些用户是第一次登入系统,如果用户是第一次登入系统,则调用spring的事件监听,记录这些用户。

主要用到的spring的类和接口有:

org.springframework.context.event.ApplicationEvent抽象类及其子类来实现事件;

org.springframework.context.ApplicationListener接口及其实现者实现事件的监听。

这两者构成了观察者模式(Observer)。

通过org.springframework.context.ApplicationContextAware接口的实现类,可以取得ApplicationContext, AlicationContext提供了publishEvent方法,实现事件的发布。

下面让我们来看下实现代码:

1 自定义事件 继承ApplicationEvent抽象类

ApplicationEvent 她继承自java.util.EventObject,其中仅仅创建了一个构造器ApplicationEvent,和一个取得当前系统事件的timestamp

public class FirstLoginUserEvent extends ApplicationEvent{

private String loginName;

public FirstLoginUserEvent(Object source){

super(source);

}

public FirstLoginUserEvent(Object source, String loginName){

super(source);

this.loginName=loginName;

System.out.println(super.getTimestamp());

System.out.println(loginName);

}

public String getLoginName(){

return loginName;

}

public void setLoginName(String loginName){

this.loginName=loginName;

}

}

2 定义监听器 继承ApplicationListener接口

@Service("firstLoginUserListener ")

public class FirstLoginUserListener implements ApplicationListener{

private static Log log = LogFactory.getLog(FirstLoginUserListener.class);

public void onApplicationEvent(ApplicationEvent event) {

if (event instanceof FirstLoginUserEvent){

FirstLoginUserEvent  firstLoginUserEvent=(FirstLoginUserEvent)

log.debug("用户:"+firstLoginUserEvent.getLoginName()+"第一次登入");

}else{

log.debug("其它事件");

}

}

}

3 发布事件

@Service("userService ")

public class UserService implements ApplicationContextAware {

private ApplicationContext applicationContext;

public void setApplicationContext (ApplicationContext applicationContext){

this.applicationContext=applicationContext;

}

public void decideUser(int num,String loginName){

if (num==0){ //用户第一次登入,发布事件

applicationContext.publishEvent(new FirstLoginUserEvent(this,loginName));

}else{

.......

}

}

}

当我们发布事件的时候,我们的监听器就会对这个事件进行监听。

在有些情况下,比如记录某个特殊操作的日志,可以用spring的事件监听来记录日志,也可以用spring的AOP来做,那么它们之间有什么区别呢? spring事件监听,是以异步方式来操作的,而AOP是同步的。这两种方式那个好呢?就得具体情况具体分析了。

Spring之事件监听相关推荐

  1. 框架源码专题:Spring的事件监听、发布机制 ApplicationListener

    文章目录 1.Spring内置事件 2.自定义事件 3.事件监听器 4.事件发布 publishEvent 4.Spring事件原理 5. 面试题:怎么样可以在所有Bean创建完后做扩展代码? 6. ...

  2. 如何实现业务解耦?spring中事件监听了解一下

    一.前言 二.业务解耦之事件监听实战         1.事件监听三大组件          2.事件发布以及监听实战案例          3.事件发布以及监听原理 一.前言 耦合这个词在平常的开发 ...

  3. spring 事件监听

    用一个简单的例子来实现spring事件监听的功能 这个例子主要功能是,记录那些用户是第一次登入系统,如果用户是第一次登入系统,则调用spring的事件监听,记录这些用户. 主要用到的spring的类和 ...

  4. spring中的事件监听机制

    Spring event listener 介绍 example 简单原理解释 自定义事件.监听和发布 事件 监听器 发布者 测试 更加一般的事件 @EventListener原理 介绍 exampl ...

  5. 事件监听机制(一)Java事件监听

    事件监听机制(一)Java事件监听 事件监听实现流程 事件对象: 继承自java.util.EventObject对象,由开发者自行定义实现. 事件源: 就是触发事件的源头,不同的事件源会触发不同的事 ...

  6. Spring5源码 - 13 Spring事件监听机制_@EventListener源码解析

    文章目录 Pre 概览 开天辟地的时候初始化的处理器 @EventListener EventListenerMethodProcessor afterSingletonsInstantiated 小 ...

  7. Spring5源码 - 12 Spring事件监听机制_异步事件监听应用及源码解析

    文章目录 Pre 实现原理 应用 配置类 Event事件 事件监听 EventListener 发布事件 publishEvent 源码解析 (反推) Spring默认的事件广播器 SimpleApp ...

  8. Spring5源码 - 11 Spring事件监听机制_源码篇

    文章目录 pre 事件监听机制的实现原理[观察者模式] 事件 ApplicationEvent 事件监听者 ApplicationEvent 事件发布者 ApplicationEventMultica ...

  9. spring boot实战(第二篇)事件监听

    前言 spring boot在启动过程中增加事件监听机制,为用户功能拓展提供极大的便利. 支持的事件类型四种 ApplicationStartedEvent ApplicationEnvironmen ...

最新文章

  1. codeforces Palindromic characteristics(hash或者dp)
  2. java注销登录_java实现注销登录
  3. Node 应用篇!推荐 10 个好用的 Node 的开源项目 YYDS
  4. Shallow-UWnet:水下图像增强新网络 2021年1月AAAI顶会论文
  5. javascript 之数据类型--01
  6. 韩顺平php视频笔记49 函数深入 php的值传递与引用传递 goto
  7. 地壳中元素含量排名记忆口诀_高中化学短周期元素推断题的常见题眼
  8. 微信小程序 Image 图片实现宽度100%,高度自适应
  9. 知乎爆赞干货:顶级大公司的OLAP数据仓库,这是全网最好的总结
  10. Linux 内存管理之 SLUB分配器(2) :kmalloc_cache 结构
  11. 迅 捷PDF编辑器去水印
  12. java class查看器_java class文件查看工具
  13. 第三方微信和支付宝的支付流程
  14. Ubuntu17.04系统安装必备软件与存在的问题
  15. 虚幻4--UE4是什么?
  16. java 多线程 数据重复,java 多线程 出现数据重复调用有关问题
  17. 胡侃EXCEL服务器设计需要的因素
  18. 两种实现模糊匹配的方法--python
  19. 大数据Hadoop视频教程
  20. 河北省高级职称计算机考试试题,河北省职称计算机考试真题.doc

热门文章

  1. mfc formview中的关闭视图函数_VC|API消息处理(回调函数+分支语句)与MFC中的消息映射函数...
  2. 微服务权限控制(二)共享Session方式的登录认证
  3. python房地产爬虫_房产中介网站爬虫实战(Python BS4+多线程)(一)
  4. 【网易游戏面试题】.NET中强引用和弱引用是什么
  5. ShadeGraph教程之节点详解5:Math Nodes
  6. 怎么画闭合线_骨骺线闭合怎么长高
  7. OpenShift 4 - 用Compliance Operator对OpenShift进行安全合规扫描
  8. WPF标签页眉控件,其中包含滚动按钮,可移动标签项和每个标签中的关闭按钮
  9. TypeScript 3.9 发布
  10. matlab流量结构分析,科学网-分享求解“结构分解分析(SDA)”各项均值的MATLAB程序-计军平的博文...