springboot学习----事件监听
来源:互联网 发布:便笺元数据损坏没事不 编辑:程序博客网 时间:2024/06/03 17:23
起源
Spring的Application拥有发布事件并且注册事件监听器的能力,拥有一套完整的事件发布和监听机制。在Java中,通过java.util. EventObject来描述事件,通过java.util. EventListener来描述事件监听器,在众多的框架和组件中,建立一套事件机制通常是基于这两个接口来进行扩展。
概念
- ApplicationEvent就是Spring的事件接口
- ApplicationListener就是Spring的事件监听器接口,所有的监听器都实现该接口
- ApplicationEventPublisher是Spring的事件发布接口,ApplicationContext实现了该接口
- ApplicationEventMulticaster就是Spring事件机制中的事件广播器,默认实现SimpleApplicationEventMulticaster
在Spring中通常是ApplicationContext本身担任监听器注册表的角色,在其子类AbstractApplicationContext中就聚合了事件广播器ApplicationEventMulticaster和事件监听器ApplicationListnener,并且提供注册监听器的addApplicationListnener方法。
执行流程
当一个事件源产生事件时,它通过事件发布器ApplicationEventPublisher发布事件,然后事件广播器ApplicationEventMulticaster会去事件注册表ApplicationContext中找到事件监听器ApplicationListnener,并且逐个执行监听器的onApplicationEvent方法,从而完成事件监听器的逻辑。
默认启动事件
- ApplicationStartedEvent
- ApplicationEnvironmentPreparedEvent
- ApplicationPreparedEvent
- ApplicationFailedEvent
源码片段
AbstractApplicationContext实现了ApplicationEventPublisher接口方法,通过ApplicationEventMulticaster广播事件
public void publishEvent(ApplicationEvent event) { Assert.notNull(event, "Event must not be null"); if(this.logger.isTraceEnabled()) { this.logger.trace("Publishing event in " + this.getDisplayName() + ": " + event); } this.getApplicationEventMulticaster().multicastEvent(event); if(this.parent != null) { this.parent.publishEvent(event); } }
spring boot 系统事件分发
EventPublishingRunListener中通过initialMulticaster广播事件
public ConfigurableApplicationContext run(String... args) { StopWatch stopWatch = new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context = null; Object analyzers = null; this.configureHeadlessProperty(); //获取RunListeners 通过SpringFactoriesLoader获取spring.factories配置 //默认实现类EventPublishingRunListener SpringApplicationRunListeners listeners = this.getRunListeners(args); //发布ApplicationStartingEvent事件 listeners.starting(); try { DefaultApplicationArguments ex = new DefaultApplicationArguments(args); //发布ApplicationEnvironmentPreparedEvent事件 ConfigurableEnvironment environment = this.prepareEnvironment(listeners, ex); Banner printedBanner = this.printBanner(environment); context = this.createApplicationContext(); new FailureAnalyzers(context); //发布ApplicationPreparedEvent事件 this.prepareContext(context, environment, listeners, ex, printedBanner); this.refreshContext(context); this.afterRefresh(context, ex); //发布ApplicationReadyEvent事件 listeners.finished(context, (Throwable)null); stopWatch.stop(); if(this.logStartupInfo) { (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch); } return context; } catch (Throwable var9) { this.handleRunFailure(context, listeners, (FailureAnalyzers)analyzers, var9); throw new IllegalStateException(var9); } }
EventPublishingRunListener 以starting为例,发布ApplicationStartedEvent启动事件
public void starting() { this.initialMulticaster.multicastEvent(new ApplicationStartedEvent(this.application, this.args)); }
SimpleApplicationEventMulticaster
public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) { ResolvableType type = eventType != null?eventType:this.resolveDefaultEventType(event); //根据事件类型获取事件对应的ApplicationListener Iterator var4 = this.getApplicationListeners(event, type).iterator(); while(var4.hasNext()) { final ApplicationListener listener = (ApplicationListener)var4.next(); //如果配置了线程池,则异步执行listener的onApplicationEvent方法 Executor executor = this.getTaskExecutor(); if(executor != null) { executor.execute(new Runnable() { public void run() { SimpleApplicationEventMulticaster.this.invokeListener(listener, event); } }); } else { this.invokeListener(listener, event); } } }//执行监听中onApplicationEvent方法protected void invokeListener(ApplicationListener listener, ApplicationEvent event) { ErrorHandler errorHandler = this.getErrorHandler(); if(errorHandler != null) { try { listener.onApplicationEvent(event); } catch (Throwable var7) { errorHandler.handleError(var7); } } else { try { listener.onApplicationEvent(event); } catch (ClassCastException var8) { String msg = var8.getMessage(); if(msg != null && !msg.startsWith(event.getClass().getName())) { throw var8; } Log logger = LogFactory.getLog(this.getClass()); if(logger.isDebugEnabled()) { logger.debug("Non-matching event type for listener: " + listener, var8); } } } }
参考
http://liuxiamai.iteye.com/blog/2322197
http://blog.csdn.net/nution/article/details/72765813
http://blog.csdn.net/chszs/article/details/49097919
- springboot学习----事件监听
- Springboot 事件监听
- 事件监听-学习笔记
- 事件监听学习笔记
- springBoot事件监听 在项目实际业务中的异步应用
- java基础学习之事件监听之键盘监听
- AWT事件监听作业学习例子
- java基础学习要点五:事件监听
- Flex 监听键盘事件(学习笔记)
- java学习笔记---事件驱动监听类
- Andorid学习笔记:事件监听合集
- 学习Android按钮以及监听事件
- 安卓学习之事件监听
- html学习 - jquery事件监听详解
- Android中监听点击事件----学习笔记
- JAVA学习笔记(四十七)- 事件监听
- Android学习之监听按钮点击事件
- java学习:创建鼠标监听事件
- spring boot之log日志
- python openpyxl学习
- 表单验证<AngularJs>
- vue中怎样让子组件改变父组件的数据呢?
- JQuery之Ajax方法
- springboot学习----事件监听
- 5类系统推荐算法
- Hive中的四种排序
- Activity取消界面切换的默认动画方法
- spring的事务管理
- XStream xml转java对象
- SSM_bug:org.mybatis.spring.MyBatisSystemException:
- [iOS]UITextField和UITextView限制输入字符数量方面
- wingIDE设置python虚拟环境并运行