// Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); }
// Destroy already created singletons to avoid dangling resources. destroyBeans();
// Reset 'active' flag. cancelRefresh(ex);
// Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
/** * Add beans that implement ApplicationListener as listeners. * Doesn't affect other listeners, which can be added without being beans. * 注册监听器 */ protectedvoidregisterListeners() { // Register statically specified listeners first. // 1.通过硬编码调用addApplicationListener方法添加的监听器处理(可以通过自定义ApplicationContextInitializer添加) for (ApplicationListener<?> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); }
//获取到实现了ApplicationListener接口的类的名称 // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let post-processors apply to them! // 2.通过配置文件或注解注入BeanFactory的监听器处理 String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); }
// Publish early application events now that we finally have a multicaster... // 3.使用事件广播器,发布早期应用程序事件到相应的监听器 Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { //多播事件,事件执行 getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }
/** * Finish the refresh of this context, invoking the LifecycleProcessor's * onRefresh() method and publishing the * 完成此上下文的刷新 * {@link org.springframework.context.event.ContextRefreshedEvent}. */ protectedvoidfinishRefresh() { // Clear context-level resource caches (such as ASM metadata from scanning). //1. 清除上下文级资源缓存 clearResourceCaches();
// Initialize lifecycle processor for this context. // 2.为此上下文初始化生命周期处理器 initLifecycleProcessor();
// Propagate refresh to lifecycle processor first. // 3.首先将刷新完毕事件传播到生命周期处理器(触发isAutoStartup方法返回true的SmartLifecycle的start方法) getLifecycleProcessor().onRefresh();
// Publish the final event. // 4.推送上下文刷新完毕事件到相应的监听器 publishEvent(newContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active. LiveBeansView.registerApplicationContext(this); }
protectedvoidpublishEvent(Object event, @Nullable ResolvableType eventType) { Assert.notNull(event, "Event must not be null");
// Decorate event as an ApplicationEvent if necessary // 1.如有必要,将事件装饰为ApplicationEvent ApplicationEvent applicationEvent; if (event instanceof ApplicationEvent) { applicationEvent = (ApplicationEvent) event; } else { applicationEvent = newPayloadApplicationEvent<>(this, event); if (eventType == null) { eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType(); } }
// Multicast right now if possible - or lazily once the multicaster is initialized if (this.earlyApplicationEvents != null) { this.earlyApplicationEvents.add(applicationEvent); } else { // 2.使用事件广播器广播事件到相应的监听器 getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType); }
// Publish event via parent context as well... // 3.同样的,通过parent发布事件...... if (this.parent != null) { if (this.parent instanceof AbstractApplicationContext) { ((AbstractApplicationContext) this.parent).publishEvent(event, eventType); } else { this.parent.publishEvent(event); } } }
/** * Invoke the given listener with the given event. * 用给定的事件调用给定的侦听器 * * @param listener the ApplicationListener to invoke * @param event the current event to propagate * @since 4.1 */ protectedvoidinvokeListener(ApplicationListener<?> listener, ApplicationEvent event) { // 1.返回此广播器的当前错误处理程序 ErrorHandlererrorHandler= getErrorHandler(); if (errorHandler != null) { try { // 2.1 如果errorHandler不为null,则使用带错误处理的方式调用给定的监听器 doInvokeListener(listener, event); } catch (Throwable err) { errorHandler.handleError(err); } } else { // 2.2 否则,直接调用调用给定的监听器 doInvokeListener(listener, event); } }
@SuppressWarnings({"rawtypes", "unchecked"}) privatevoiddoInvokeListener(ApplicationListener listener, ApplicationEvent event) { try { // 触发监听器的onApplicationEvent方法,参数为给定的事件 listener.onApplicationEvent(event); } catch (ClassCastException ex) { Stringmsg= ex.getMessage(); if (msg == null || matchesClassCastMessage(msg, event.getClass())) { // 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. Loglogger= LogFactory.getLog(getClass()); if (logger.isTraceEnabled()) { logger.trace("Non-matching event type for listener: " + listener, ex); } } else { throw ex; } } }
自定义监听器实现
如果我们想在 Spring IoC 容器构建完毕之后进行一些逻辑,就可以通过监听器来实现。
创建一个自定义监听器,实现 ApplicationListener 接口,监听 ContextRefreshedEvent(上下文刷新完毕事件),并且将该监听器注册到 Spring IoC 容器即可。