学习过Spring 的同学对下面的代码应该会很熟悉:
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
就这么简单一行代码就创建了Ioc 容器,下面我们就深入源码看看里面的具体实现细节。
构造方法会调用另外一个构造方法this(new String[]{configLocation}, true, (ApplicationContext)null);
,深入该方法,来看看细节:
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException {
super(parent);
//设置配置文件的位置
this.setConfigLocations(configLocations);
if(refresh) {
//refresh 方法封装了很多实现细节,很重要
this.refresh();
}
}
上面的代码中,我们的重点是要放在refresh
方法上,接下来就进入到该方法中去,发现该方法在
类AbstractApplicationContext
中实现, 下面是细节:
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();//创建beanFactory前的一些操作
//这行代码非常重要
//其中obtainFreshBeanFactory方法的功能有下面两点:
//1. 获取beanFactory(beanFactory是DefaultListableBeanFactory类型的实例对象,如果已经存在beanFactory也要重新创建BeanFactory)
//2.在获取到对象beanFactory后,执行loadBeanDefinitions(beanFactory)来Load BeanDefinition,目的是将解析的Bean定义存入beanDefinitionNames和beanDefinitionMap
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
//该行代码功能是给前面已经创建好的beanFactory设置属性
this.prepareBeanFactory(beanFactory);
try {
//postProcessBeanFactory方法是protected,具体由子类实现,
//功能-对创建的好的beanFactory进行修改
this.postProcessBeanFactory(beanFactory);
//下面一行的代码实现的功能如下:
//1.初始化和执行实现了BeanFactoryPostProcessor接口的bean
//2.beanFactory中add实现了BeanPostProcessor借口的bean
this.invokeBeanFactoryPostProcessors(beanFactory);
//初始化和执行继承了BeanPostProcessor 的bean
this.registerBeanPostProcessors(beanFactory);
//初始化beanFactory的MessageSource
this.initMessageSource();
//初始化beanFactory的event multicaster
this.initApplicationEventMulticaster();
this.onRefresh();//protected方法,由子类实现
this.registerListeners();//检查注册事件?
//下面这行代码非常重要!Bean的实例化操作(主要功能是初始化 非lazy-init的bean,且为单例)
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if(this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();//当出现异常Exception就销毁beans
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}