下面看一下Context和Resource是如何建立關(guān)系的?首先看一下他們的類關(guān)系圖:

圖9.Context和Resource的類關(guān)系圖
從上圖可以看出,Context是把資源的加載、解析和描述工作委托給了ResourcePatternResolver類來(lái)完成,他相當(dāng)于一個(gè)接頭人,他把資源的加載、解析和資源的定義整合在一起便于其他組件使用。 Core組件中還有很多類似的方式。
Ioc容器如何工作
前面介紹了Core組件、Bean組件和Context組件的結(jié)構(gòu)與相互關(guān)系,下面這里從使用者角度看一下他們是如何運(yùn)行的,以及我們?nèi)绾巫孲pring完成各種功能,Spring到底能有那些功能,這些功能是如 何得來(lái)的,下面介紹。
如何創(chuàng)建BeanFactory工廠
正如圖2描述的那樣,Ioc容器實(shí)際上就是Context組件結(jié)合其他兩個(gè)組件共同構(gòu)建了一個(gè)Bean關(guān)系網(wǎng),如何構(gòu)建這個(gè)關(guān)系網(wǎng)?構(gòu)建的入口就在AbstractApplicationContext類的refresh方法中。這個(gè)方 法的代碼如下:
清單1.AbstractApplicationContext.refresh
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& nbsp;the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean crea tion.
registerBeanPostProcessors (beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific contex t 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) {
// Destroy already created singletons to avoid dangl ing resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
}
}
這個(gè)方法就是構(gòu)建整個(gè)Ioc容器過(guò)程的完整的代碼,了解了里面的每一行代碼基本上就了解大部分Spring的原理和功能了。
這段代碼主要包含這樣幾個(gè)步驟:
◆構(gòu)建BeanFactory,以便于產(chǎn)生所需的“演員”
◆注冊(cè)可能感興趣的事件
◆創(chuàng)建Bean實(shí)例對(duì)象
◆觸發(fā)被監(jiān)聽(tīng)的事件
下面就結(jié)合代碼分析這幾個(gè)過(guò)程。
第二三句就是在創(chuàng)建和配置BeanFactory。這里是refresh也就是刷新配置,前面介紹了Context有可更新的子類,這里正是實(shí)現(xiàn)這個(gè)功能,當(dāng)BeanFactory已存在是就更新,如果沒(méi)有就新創(chuàng)建。下面是 更新BeanFactory的方法代碼:
清單2. AbstractRefreshableApplicationContext. refreshBeanFactory
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException(
"I/O error& nbsp;parsing bean definition source for "
+ getDisplayName (), ex);
}
}
這個(gè)方法實(shí)現(xiàn)了AbstractApplicationContext的抽象方法refreshBeanFactory,這段代碼清楚的說(shuō)明了BeanFactory的創(chuàng)建過(guò)程。注意BeanFactory對(duì)象的類型的變化,前 面介紹了他有很多子類,在什么情況下使用不同的子類這非常關(guān)鍵。BeanFactory的原始對(duì)象是DefaultListableBeanFactory,這個(gè)非常關(guān)鍵,因?yàn)樗O(shè)計(jì)到后面對(duì)這個(gè)對(duì)象的多種操作,下面看一下這個(gè) 類的繼承層次類圖: