Spring IoC原理(二) refresh()方法
一、refresh()方法介绍
对于IoC容器启动来说,refresh是十分重要的方法。该方法在抽象类AbstractApplication中,在该方法中详细的描述了整个ApplicationContext的初始化过程,同时作为Spring中的具体ApplicationContext的基类,为Bean的生命周期管理提供了条件。
图1-1 AbstractApplicationContext继承关系
二、refresh()方法源码
下面是refresh()方法的源码,在重要的方法处都添加了相关的注释,可以看出方法名字定义很清晰,可以大概了解方法的功能。refresh()方法更像是一个模板,其对ApplicationContext的创建过程列出了一个提纲,后续将按照refresh()方法列出的方法提纲逐个进行分析。
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 设置上下文 获取属性
prepareRefresh();
// 获取全新的BeanFactory 将原来的BeanFactory销毁
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 准备Bean工厂
prepareBeanFactory(beanFactory);
try {
// 允许子类上下文对BeanFactory进行后置处理
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// 实例化所有注册的BeanFactory的后置处理器
invokeBeanFactoryPostProcessors(beanFactory);
// 实例化并注册在BeanFactory中扩展了BeanPostPorcessor的Bean
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// 初始化国际化工具MessageSource
initMessageSource();
// 初始化事件广播器
initApplicationEventMulticaster();
// 模板方法,可以自定义刷新的逻辑
onRefresh();
// 注册监听器
registerListeners();
// 对非懒加载的Bean进行创建
finishBeanFactoryInitialization(beanFactory);
// 结束refresh并发布事件
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();
contextRefresh.end();
}
}
}