這裏需要貼兩張圖 ClassPathXmlApplicationContext 繼承關係樹
這張圖實際沒畫全,最上層爲
DefaultResourceLoader,該類設置classLoader,並且將配置文件 封裝爲Resource文件 Resrource根據傳入的路徑的前綴來判斷採取何種封裝。
AbstractApplicationContext,該類完成了大部分的IOC容器初始化工作,同時也提供了擴展接口留給子類去重載。該類的refresh()函數是核心初始化操作。
AbstractRefreshableApplicationContext,該類定義了是否允許bean在運行時是否重新定義,以及包含了beanFactory。該類主要是和beanFactory打交道。
AbstractRefreshableConfigApplicationContext,該類保存了配置文件路徑
AbstractXmlApplicationContext:該類封裝瞭如何讀取Resource封裝的配置
最後ClassPathXmlApplicationContext:只提供了一個簡單的構造函數
Spring 將類職責分開,形成職責鏈,每一層次的擴展 都只是添加了某個功能
然後父類定義大量的模板,讓子類實現,父類層層傳遞到子類 知道某個子類重載了抽象方法。這裏應用到了職責鏈設計模式和模板設計模式,IOC是個容器工廠設計模式。
IOC容器的行爲也跟其組件有關,這可以認爲是策略模式。
現在根據這個調用流程圖 我們大概就可以瞭解到 Spring容器初始化的最主要的工作就是refresh()函數所做的
AbstractApplicationContext:refresh()函數
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
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();
}
}
}
事實上 我們看到的這些方法 可以認爲是一種模板設計模式 裏面有些方法 並沒有實現 只是一個在AbstractApplicationContext所定義的抽象方法,這些抽象方法直到某一子類才得以實現。一般refresh()函數調用完成 那麼ioc容器也就進入了可以使用的階段。