學習過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();
}
}
}