文章目录
-
- 3.7 IOC容器的启动流程
-
- 1.prepareRefresh——初始化前的预处理
- 2.obtainFreshBeanFactory——初始化BeanFactory
- 3.prepareBeanFactory——BeanFactory的预处理动作
- 4.postProcessBeanFactory——BeanFactory的后置处理
- 5.invokeBeanFactoryPostProcessors——执行BeanFactoryPostProcessors
- 6.registerBeanPostProcessors——初始化BeanPostProcessor
- 7.initMessageSource——初始化国际化组件
- 8.initApplicationEventMulticaster——初始化事件广播器
- 9.onRefresh——子类扩展的刷新动作
- 10.registerListeners——注册监听器
- 11.finishBeanFactoryInitialization——初始化剩余的单实例bean对象
- 12.finishRefresh——刷新后的动作
- 13.resetCommonCaches——清除缓存
- 3.8 小结
3.7 IOC容器的启动流程
在 SpringBoot源码解读与原理分析(八)ApplicationContext 中,梳理了是ApplicationContext的几个重要实现类,其中AbstractApplicationContext显得尤为重要:
ApplicationContext的启动,其内部的核心动作的刷新容器,也就是AbstractApplicationContext中的refresh()方法。
AbstractApplicationContext.java
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.获取BeanFactory,加载所有bean的定义信息(未实例化)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 3.BeanFactory的预处理配置
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 4.准备BeanFactory完成后进行的后置处理
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 5.执行BeanFactory创建后的后置处理器
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 6.注册Bean的后置处理器
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 7.初始化MessageSource
initMessageSource();
// Initialize event multicaster for this context.
// 8.初始化事件广播器
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 9.子类的多态onRefresh
onRefresh();
// Check for listener beans and register them.
// 10.注册监听器
registerListeners();
// 至此,BeanFactory创建完成
// Instantiate all remaining (non-lazy-init) singletons.
// 11.初始化所有剩下的单实例
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...
// 13.清理缓存
resetCommonCaches();
}
}
}
整个refresh方法分为13步,这篇文章只是梳理每一步都做了哪些事情,对于其中的细节设计放到之后的文章再展开。
1.prepareRefresh——初始化前的预处理
/**
* Prepare this context for refreshing, setting its startup date and
* active flag as well as performing any initialization of property sources.
*/
protected void prepareRefresh() {
// Switch to active.
// 切换IOC容器启动状态
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
} else {
logger.debug("Refreshing " + getDisplayName());
}
}
// Initialize any placeholder property sources in the context environment.
// 在上下文环境中初始化任何占位符属性源
initPropertySources();
// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
// 验证标记为required的所有属性都是可解析的
getEnvironment().validateRequiredProperties();
// Store pre-refresh ApplicationListeners...
// 存储预刷新的ApplicationListeners
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
} else {
// Reset local application listeners to pre-refresh state.
// 将本地应用程序监听器重置为预刷新状态。
this.applicationListeners.clear();
this.applicationListeners.addAll(this.ea