[Spring]new ClassPathXmlApplicationContext("application.xml")做了些什麼

這裏需要貼兩張圖 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容器也就進入了可以使用的階段。





發佈了58 篇原創文章 · 獲贊 11 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章