上一篇我们在Spring源码十三:非懒加载单例Bean中看到了Spring会在refresh方法中去调用我们的finishBeanFactoryInitialization方法去实例化,所有非懒加载器单例的bean。并实例化后的实例放到单例缓存中。到此我们refresh方法已经接近尾声。
Spring的生命周期
今天我们来看refresh方法中的最后一块逻辑:
@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// Prepare this context for refreshing. 1、初始化上下文信息,替换占位符、必要参数的校验prepareRefresh();// Tell the subclass to refresh the internal bean factory. 2、解析类Xml、初始化BeanFactoryConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 这一步主要是对初级容器的基础设计// Prepare the bean factory for use in this context. 3、准备BeanFactory内容:prepareBeanFactory(beanFactory); // 对beanFactory容器的功能的扩展:try {// Allows post-processing of the bean factory in context subclasses. 4、扩展点加一:空实现,主要用于处理特殊Bean的后置处理器postProcessBeanFactory(beanFactory);// Invoke factory processors registered as beans in the context. 5、spring bean容器的后置处理器invokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation. 6、注册bean的后置处理器registerBeanPostProcessors(beanFactory);// Initialize message source for this context. 7、初始化消息源initMessageSource();// Initialize event multicaster for this context. 8、初始化事件广播器initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses. 9、扩展点加一:空实现;主要是在实例化之前做些bean初始化扩展onRefresh();// Check for listener beans and register them. 10、初始化监听器registerListeners();// Instantiate all remaining (non-lazy-init) singletons.// 11、实例化:非懒加载BeanfinishBeanFactoryInitialization(beanFactory);//!!!!!!!!!!!! 这里 这里 今天看这里 !!!!!!!!!!!//// Last step: publish corresponding event.// 12、初始化生命周期处理器,发布相应的事件通知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();}}}
finishRefresh
我们进入finishRefresh方法中去:
/*** Finish the refresh of this context, invoking the LifecycleProcessor's* onRefresh() method and publishing the* 完成应用上下文的刷新过程。此方法确保所有的资源和组件都已初始化,* 并发布相应的事件通知监听器* {@link org.springframework.context.event.ContextRefreshedEvent}.*/protected void finishRefresh() {// Clear context-level resource caches (such as ASM metadata from scanning).// 清除上下文级别的资源缓存clearResourceCaches();// Initialize lifecycle processor for this context.// 初始化化生命周期处理器initLifecycleProcessor();// Propagate refresh to lifecycle processor first.getLifecycleProcessor().onRefresh();// Publish the final event.// 发布已经刷新完成的事件publishEvent(new ContextRefreshedEvent(this));// Participate in LiveBeansView MBean, if active.// 将Application容器注册到LiveBeanView中LiveBeansView.registerApplicationContext(this);}
上述注释已经比较完整了,finishRefresh方法我们在整理总结下:主要是初始化和生命周期相关的一些组件,我们可以先到initLifecycleProcessor的方法,看下具体做了些什么?
/*** 初始化生命周期组件,如果beanFactory没有定义,* 则使用DefaultLifecycleProcessor初始化一个* 默认的生命周期组件,注册到容器中* Initialize the LifecycleProcessor.* Uses DefaultLifecycleProcessor if none defined in the context.* @see org.springframework.context.support.DefaultLifecycleProcessor*/protected void initLifecycleProcessor() {// 获取BeanFactory容器ConfigurableListableBeanFactory beanFactory = getBeanFactory();// 判断容器中是否存在lifecycleProcessorif (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {// 获取lifecycleProcessor,注册当前容器(AbstractApplicationContext)this.lifecycleProcessor =beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);if (logger.isTraceEnabled()) {logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");}}else {// 如果容器中没有lifecycleProcessor,则初始化DefaultLifecycleProcessorDefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();defaultProcessor.setBeanFactory(beanFactory);// 设置成员属性this.lifecycleProcessor = defaultProcessor;// 注册到Spring容器中beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);if (logger.isTraceEnabled()) {logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +"[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");}}}
可以看到在方法initLifecycleProcessor中,首先看下beanFactory中是否有名称为lifecycleProcessor的bean,存在直接获并复制给abstractApplicationContext的成员变量lifecycleProcessor,如果不存在,Spring框架会自动创建DefaultLifecycleProcessor类型的对象,赋值给成员变量,最后再注入到Spring容器中
DefaultLifecycleProcessor
进入DefaultLifecycleProcessor类中:
可以看到它主要实现了LifecycleProcessor, BeanFactoryAware这两个接口,我们来看下它的类图,如下所示:
看左边这块,DefaultLifecycleProcessor最终也是实现了Lifecycle接口与LifecycleProcessor接口我们展开看下这两个接口:
在Spring中,如果实现了接口Lifecycle,Spirng会在容器启动时,调用这些Bean中的start方法开启他们的生命周期,同样:如果在Spring容器关闭时也会调用stop方法来结束他们的生命周期。
而LifecycleProcessor在此基础上又新增了onRefrsh方法和onClose方法,主用来处理对应Bean的状态。
方法调用如下:
// // Propagate refresh to lifecycle processor first.// getLifecycleProcessor().onRefresh();/*** 调用DefaultLifecycleProcessor.onRefresh()*/@Overridepublic void onRefresh() {startBeans(true);this.running = true;}// Internal helpersprivate void startBeans(boolean autoStartupOnly) {// 1、获取所有lifecycle类型的BeanMap<String, Lifecycle> lifecycleBeans = getLifecycleBeans();Map<Integer, LifecycleGroup> phases = new HashMap<>();lifecycleBeans.forEach((beanName, bean) -> {if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {int phase = getPhase(bean);LifecycleGroup group = phases.get(phase);if (group == null) {group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);phases.put(phase, group);}group.add(beanName, bean);}});// 遍历 Map,排序后启动if (!phases.isEmpty()) {List<Integer> keys = new ArrayList<>(phases.keySet());Collections.sort(keys);for (Integer key : keys) {phases.get(key).start();}}}
可以看到在onRefresh方法中,像我们刚才分析的一样,就会从Spring容器中获取所有实现了Lifecycle接口的bean,然后调用start方法来开启它们的生命周期,也就是开启Spring的生命周期了。
publishEvent
接着往下看:
// 发布已经刷新完成的事件publishEvent(new ContextRefreshedEvent(this));/*** Publish the given event to all listeners.* 发布事件,通知所有监听器* <p>Note: Listeners get initialized after the MessageSource, to be able* to access it within listener implementations. Thus, MessageSource* implementations cannot publish events.* @param event the event to publish (may be application-specific or a* standard framework event)*/@Overridepublic void publishEvent(ApplicationEvent event) {publishEvent(event, null);}/**** Publish the given event to all listeners.* 用于将指定的事件发布给所有监听器* @param event the event to publish (may be an {@link ApplicationEvent}* 参数表示要发布的事件,可以是 ApplicationEvent* or a payload object to be turned into a {@link PayloadApplicationEvent})* 或一个负载对象(将被转换为 PayloadApplicationEvent)。* ** @param eventType the resolved event type, if known* @since 4.2*/protected void publishEvent(Object event, @Nullable ResolvableType eventType) {Assert.notNull(event, "Event must not be null");// Decorate event as an ApplicationEvent if necessary// 判断传入的 event 是否为 ApplicationEvent 的实例:// 如果是,则直接赋值给 applicationEvent。// 如果不是,则将其包装为 PayloadApplicationEvent。ApplicationEvent applicationEvent;if (event instanceof ApplicationEvent) {applicationEvent = (ApplicationEvent) event;}else {applicationEvent = new PayloadApplicationEvent<>(this, event);// 如果 eventType 为空且事件被包装为 PayloadApplicationEvent,则从包装的事件中获取事件类型if (eventType == null) {eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();}}// 事件分发// Multicast right now if possible - or lazily once the multicaster is initialized:// 判断 earlyApplicationEvents 是否不为空// 如果不为空,说明广播器还未初始化,则将事件添加到 earlyApplicationEvents 队列中,等待广播器初始化后再分发。// 如果为空,说明广播器已初始化, 立即分发事件。if (this.earlyApplicationEvents != null) {this.earlyApplicationEvents.add(applicationEvent);}else {// 直接通过 getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);}// Publish event via parent context as well...// 如果当前上下文有父上下文 (this.parent 不为空),则同样向父上下文发布事件:if (this.parent != null) {//如果父上下文是 AbstractApplicationContext 的实例,则调用其 publishEvent 方法,同时传递事件和事件类型。// 如果不是,则直接调用父上下文的 publishEvent 方法。if (this.parent instanceof AbstractApplicationContext) {((AbstractApplicationContext) this.parent).publishEvent(event, eventType);}else {this.parent.publishEvent(event);}}}
根据我们两篇关于事件驱动的源码分析,事件ContextRefreshedEvent将会注册到广播器中,广播器会把该事件广播器相应的监听器去处理,这个事件相当于告诉Spring整个容器已经刷新了,也就说Spring容器ApplicationContext已经初始化完毕了。