IoC 是指在程序開發(fā)中,實例的創(chuàng)建不再由調(diào)用者管理,而是由 Spring 容器創(chuàng)建。Spring 容器會負(fù)責(zé)控制程序之間的關(guān)系,而不是由程序代碼直接控制,因此,控制權(quán)由程序代碼轉(zhuǎn)移到了 Spring 容器中,控制權(quán)發(fā)生了反轉(zhuǎn),這就是 Spring 的 IoC 思想。
Spring 提供了兩種 IoC 容器,分別為 BeanFactory 和 ApplicationContext,接下來將針對這兩種 IoC 容器進(jìn)行詳細(xì)講解。
BeanFactory
BeanFactory 是基礎(chǔ)類型的 IoC 容器,它由 org.springframework.beans.facytory.BeanFactory 接口定義,并提供了完整的 IoC 服務(wù)支持。簡單來說,BeanFactory 就是一個管理 Bean 的工廠,它主要負(fù)責(zé)初始化各種 Bean,并調(diào)用它們的生命周期方法。
BeanFactory 接口有多個實現(xiàn)類,最常見的是 org.springframework.beans.factory.xml.XmlBeanFactory,它是根據(jù) XML 配置文件中的定義裝配 Bean 的。
創(chuàng)建 BeanFactory 實例時,需要提供 Spring 所管理容器的詳細(xì)配置信息,這些信息通常采用 XML 文件形式管理。其加載配置信息的代碼具體如下所示:
BeanFactory beanFactory = new XmlBeanFactory(new FileSystemResource("D://applicationContext.xml"));
ApplicationContext
ApplicationContext 是 BeanFactory 的子接口,也被稱為應(yīng)用上下文。該接口的全路徑為 org.springframework.context.ApplicationContext,它不僅提供了 BeanFactory 的所有功能,還添加了對 i18n(國際化)、資源訪問、事件傳播等方面的良好支持。
ApplicationContext 接口有兩個常用的實現(xiàn)類,具體如下。
1)ClassPathXmlApplicationContext
該類從類路徑 ClassPath 中尋找指定的 XML 配置文件,找到并裝載完成 ApplicationContext 的實例化工作,具體如下所示。
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(String configLocation);
在上述代碼中,configLocation 參數(shù)用于指定 Spring 配置文件的名稱和位置,如 applicationContext.xml。
2)FileSystemXmlApplicationContext
該類從指定的文件系統(tǒng)路徑中尋找指定的 XML 配置文件,找到并裝載完成 ApplicationContext 的實例化工作,具體如下所示。
ApplicationContext applicationContext = new FileSystemXmlApplicationContext(String configLocation);
它與 ClassPathXmlApplicationContext 的區(qū)別是:在讀取 Spring 的配置文件時,F(xiàn)ileSystemXmlApplicationContext 不再從類路徑中讀取配置文件,而是通過參數(shù)指定配置文件的位置,它可以獲取類路徑之外的資源,如“F:/workspaces/applicationContext.xml”。
在使用 Spring 框架時,可以通過實例化其中任何一個類創(chuàng)建 Spring 的 ApplicationContext 容器。
通常在 Java 項目中,會采用通過 ClassPathXmlApplicationContext 類實例化 ApplicationContext 容器的方式,而在 Web 項目中,ApplicationContext 容器的實例化工作會交由 Web 服務(wù)器完成。Web 服務(wù)器實例化 ApplicationContext 容器通常使用基于 ContextLoaderListener 實現(xiàn)的方式,它只需要在 web.xml 中添加如下代碼:
<!--指定Spring配置文件的位置,有多個配置文件時,以逗號分隔--> <context-param> <param-name>contextConfigLocation</param-name> <!--spring將加載spring目錄下的applicationContext.xml文件--> <param-value> classpath:spring/applicationContext.xml </param-value> </context-param> <!--指定以ContextLoaderListener方式啟動Spring容器--> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener>
需要注意的是,BeanFactory 和 ApplicationContext 都是通過 XML 配置文件加載 Bean 的。
二者的主要區(qū)別在于,如果 Bean 的某一個屬性沒有注入,則使用 BeanFacotry 加載后,在第一次調(diào)用 getBean() 方法時會拋出異常,而 ApplicationContext 則在初始化時自檢,這樣有利于檢查所依賴的屬性是否注入。
因此,在實際開發(fā)中,通常都選擇使用 ApplicationContext,而只有在系統(tǒng)資源較少時,才考慮使用 BeanFactory。本教程中使用的就是 ApplicationContext。