Spring源码十四:Spring生命周期

csdn推荐

上一篇我们在Spring源码十三:非懒加载单例Bean中看到了Spring会在refresh方法中去调用我们的finishBeanFactoryInitialization方法去实例化,所有非懒加载器单例的bean。并实例化后的实例放到单例缓存中。到此我们refresh方法已经接近尾声。

Spring的生命周期

今天我们来看refresh方法中的最后一块逻辑:

@Override
	public 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、初始化BeanFactory
			ConfigurableListableBeanFactory 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、实例化:非懒加载Bean
				finishBeanFactoryInitialization(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();
		// 判断容器中是否存在lifecycleProcessor
		if (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,则初始化DefaultLifecycleProcessor
			DefaultLifecycleProcessor 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()
	 */
	@Override
	public void  onRefresh() {
		startBeans(true);
		this.running = true;
	}
// Internal helpers
	private void startBeans(boolean autoStartupOnly) {
		// 1、获取所有lifecycle类型的Bean
		Map lifecycleBeans = getLifecycleBeans();
		Map 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 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.
	 * 发布事件,通知所有监听器
	 * 

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) */ @Override public 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已经初始化完毕了。

总结

文章来源:https://blog.csdn.net/weixin_40735063/article/details/140231272



微信扫描下方的二维码阅读本文

© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容