上一篇我们在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<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)
*/
@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已经初始化完毕了。