springboot源码----EventPublishingRunListener

EventPublishingRunListener 类实现了SpringApplicationRunListener接口,那么在springboot启动的过程中都会对这个类进行回调通知,那么通知什么? 其实看源码可以看出来里面对所有通知其实都是回调了ApplicationListener接口,说白了就是他就是一个ApplicationListener的代理。springboot启动的几个主要过程的监听通知都是通过他来进行回调
首先看下starting方法:

@Override public void starting() { this.initialMulticaster.multicastEvent( new ApplicationStartingEvent(this.application, this.args)); }

第一步调用了SimpleApplicationEventMulticaster类的multicastEvent方法并且传入了ApplicationStartingEvent对象。
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) { ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event)); for (final ApplicationListener listener : getApplicationListeners(event, type)) { Executor executor = getTaskExecutor(); if (executor != null) { executor.execute(() -> invokeListener(listener, event)); } else { invokeListener(listener, event); } } }

紧接着遍历了每个事件是ApplicationStartingEvent的监听器
@SuppressWarnings({"unchecked", "rawtypes"}) private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) { try { listener.onApplicationEvent(event); } catch (ClassCastException ex) { String msg = ex.getMessage(); if (msg == null || matchesClassCastMessage(msg, event.getClass().getName())) { // Possibly a lambda-defined listener which we could not resolve the generic event type for // -> let's suppress the exception and just log a debug message. Log logger = LogFactory.getLog(getClass()); if (logger.isDebugEnabled()) { logger.debug("Non-matching event type for listener: " + listener, ex); } } else { throw ex; } } }

最后进行回调
这边有几个问题:
  • EventPublishingRunListener是什么时候初始化的
  • SimpleApplicationEventMulticaster类里面的ApplicationListener实现类是怎么来的
EventPublishingRunListener初始化在前面一遍文章中已经介绍过
这边主要看下EventPublishingRunListener的构造器:
public EventPublishingRunListener(SpringApplication application, String[] args) { this.application = application; this.args = args; this.initialMulticaster = new SimpleApplicationEventMulticaster(); for (ApplicationListener listener : application.getListeners()) { this.initialMulticaster.addApplicationListener(listener); } }

这边可以看出来在EventPublishingRunListener初始化的时候会把SpringApplication带进来,而SpringApplication的对象中就有ApplicationListener的实现类 实在ApplicationListener初始化的时候生成的。
注意下contextLoaded方法
@Override public void contextLoaded(ConfigurableApplicationContext context) { for (ApplicationListener listener : this.application.getListeners()) { if (listener instanceof ApplicationContextAware) { ((ApplicationContextAware) listener).setApplicationContext(context); } context.addApplicationListener(listener); } this.initialMulticaster.multicastEvent( new ApplicationPreparedEvent(this.application, this.args, context)); }

这边这个方法比前面的方法特殊了一点,前面的方法直接调用this.initialMulticaster.multicastEvent就结束了。这边还做了另外两件事
  • 1 遍历了SpringApplication中所有的ApplicationListener实现类,如果有实现类还实现了ApplicationContextAware接口 就把上下文给其设置进去
  • 2 将这些 ApplicationListener实现类全部加入到上下文中(这个大家应该比较属性我们实现自己的监听的时候也会这么做)
这个方法是个分水岭 在这个方法之前的回到方法全部是通过SimpleApplicationEventMulticaster来进行回调
然后在这个之后的方法就全部通过context.publishEvent来进行回调
【springboot源码----EventPublishingRunListener】这也不难理解 因为只有到了contextLoaded方法之后才有了上下 之前还没有上下文所以只能通过SimpleApplicationEventMulticaster类进行回调所有的ApplicationListener实现类

    推荐阅读