Spring
源码 - 容器刷新finishRefresh()
Spring
版本:Spring 5.3.13-release
Spring
中提供了Lifecycle
接口,Lifecycle
接口中包含start()
、stop()
以及isRunning()
方法,实现此接口后Spring
会保证在启动的时候调用其start()
方法开始生命周期,并在Spring
关闭的时候调用stop()
方法来结束生命周期。通常用来配置后台程序,在启动后一直运行(如对MessageQueue
进行轮询等操作)。Spring
的容器刷新最后一步正是保证这一个功能的实现。
finishRefresh()
完成容器刷新AbstarctApplicationContext#finishRefresh()
代码:
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.
// 刷新所有实现了 Lifecycle 接口的 Bean
getLifecycleProcessor().onRefresh();
// Publish the final event.
// 发布 ContextRefreshEvent 事件告知容器已完成刷新
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
if (!NativeDetector.inNativeImage()) {
LiveBeansView.registerApplicationContext(this);
}
}
initLifecycleProcessor()
初始化LifecycleProcessor
ApplicationContext
在启动或停止时, 它会通过LifecycleProcessor
来与所有声明的Bean
的周期做状态更新,这一步就是初始化LifecycleProcessor
。需要注意的是,Spring
会先从容器中获取BeanName
为lifecycleProcessor
的Bean
实例,如果没有则使用Spring
默认的DefaultLifecycleProcessor
。所以开发者需要自定义LifecycleProcessor
时一定需要将自己定义的LifecycleProcessor
声明为lifecycleProcessor
。
ApplicationContext#initLifecycleProcessor()
代码:
protected void initLifecycleProcessor() {
// 获取 BeanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 如果工厂中包存在 BeanName 为 lifecycleProcessor 的 Bean
if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
// 获取该 Bean
this.lifecycleProcessor =
beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
if (logger.isTraceEnabled()) {
logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
}
}
else {
// 工厂中不存在 BeanName 为 lifecycleProcessor 的 Bean
// 使用 Spring 默认的 DefaultLifecycleProcessor
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
// 设置 BeanFactory
defaultProcessor.setBeanFactory(beanFactory);
// 赋值给当前容器中的 lifecycleProcessor
this.lifecycleProcessor = defaultProcessor;
// 以 BeanNam 为 lifecycleProcessor 注册到容器中
beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
if (logger.isTraceEnabled()) {
logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
"[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
}
}
}
getLifecycleProcessor().onRefresh()
刷新所有实现了 Lifecycle
接口的 Bean
将LifecycleProcessor
初始化完成之后,调用LifecycleProcessor
接口的onRefresh()
方法刷新所有实现了Lifecycle
的Bean
。
DefaultLifecycleProcessor#startBeans()
代码:
private void startBeans(boolean autoStartupOnly) {
// 获取所有实现了 Lifecycle 接口的 Bean
Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
Map<Integer, LifecycleGroup> phases = new TreeMap<>();
// 对需要进行启动的 Bean 进行筛选
lifecycleBeans.forEach((beanName, bean) -> {
if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
int phase = getPhase(bean);
phases.computeIfAbsent(
phase,
p -> new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly)
).add(beanName, bean);
}
});
if (!phases.isEmpty()) {
// 启动
phases.values().forEach(LifecycleGroup::start);
}
}
publishEvent()
发布容器刷新完成事件当完成ApplicationContext
容器刷新时,Spring
通过事件发布机制发布ContextRefreshedEvent
事件。以保证对应的监听器可以做进一步的逻辑处理。
AbstractApplicationContext#publishEvent()
代码:
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
Assert.notNull(event, "Event must not be null");
// Decorate event as an ApplicationEvent if necessary
// 将事件封装为 ApplicationEvent
ApplicationEvent applicationEvent;
if (event instanceof ApplicationEvent) {
applicationEvent = (ApplicationEvent) event;
}
else {
applicationEvent = new PayloadApplicationEvent<>(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 {
// 使用事件广播器, 广播事件
getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
}
// Publish event via parent context as well...
if (this.parent != null) {
if (this.parent instanceof AbstractApplicationContext) {
((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
}
else {
this.parent.publishEvent(event);
}
}
}
至此Spring
容器已完成刷新。
GitHub源码地址:https://github.com/kapbc/kapcb-spring-source/tree/master/Spring-Framework-v5.3.13
备注:此文为笔者学习
Spring
源码的笔记,鉴于本人技术有限,文中难免出现一些错误,感谢大家批评指正。