springboot学习----事件监听

xiaoxiao2021-02-28  55

起源

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方法,从而完成事件监听器的逻辑。

默认启动事件

ApplicationStartedEventApplicationEnvironmentPreparedEventApplicationPreparedEventApplicationFailedEvent

源码片段

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

转载请注明原文地址: https://www.6miu.com/read-80880.html

最新回复(0)