IoC容器的初始化过程
2019-08-27 本文已影响0人
HelloWide
之前讲解了Spring IoC容器设计,在了解整体设计思路的基础上,让我们再来看看容器的初始化过程;
简单来说,Ioc容器的初始化过程是由AbstractApplicationContext.refresh()来启动的,具体主要包含三个基本过程:Resource定位,载入和注册;
定位
通过ResourceLoader统一的getResource接口完成对BeanDefinition的资源定位查找,例如常见的FileSystemResource,ClassPathResource等;
BeanDefinition载入
就是将业务bean转换为Spring容器中的数据结构(BeanDefinition)
注册
通过调用BeanDefinitionRegistry接口将BeanDefinition注册到Ioc容器当中;实际容器内部将BeanDefinition注入到一个map当中去,key为beanName,value为BeanDefinition
容器启动核心方法解读
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 准备初始化.
prepareRefresh();
// 子类中启动refreshBeanFactory().
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 准备上下文环境,例如类加载器、事件处理器等
prepareBeanFactory(beanFactory);
try {
// 设置beanFactory的后置处理.
postProcessBeanFactory(beanFactory);
// 调用beanFactory的后处理器,这些处理器是在Bean定义中向容器注册的.
invokeBeanFactoryPostProcessors(beanFactory);
// 设置bean的后置处理.
registerBeanPostProcessors(beanFactory);
// 对下文的消息源进行初始化.
initMessageSource();
// 初始化上下文的事件广播机制.
initApplicationEventMulticaster();
// 初始化其他特俗,自定义的bean.
onRefresh();
// 检查监听bean并且将这些bean注册到容器中.
registerListeners();
// 实例化所有的懒加载(non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// 发布容易事件,结束Refresh过程.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 为防止bean的资源占用,销毁已经在前面过程中生成的单例bean.
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();
}
}
}