org.springframework.context.ApplicationContext 表明 Spring IoC 容器,並負責實例化,配置和組裝上述 bean 。容器經過讀取配置元數據得到哪些對象須要實例化、配置和組裝的指定。配置元數據能夠在XML、Java註解和Java代碼中配置。它運行你描述組成你應用程序的對象和對象之間複雜的關係。web
Spring提供了一些開箱即用的ApplicationContext接口的實現。在獨立的應用程序中,通常能夠建立ClassPathXmlApplicationContext或FileSystemXmlApplicationContext的實例。雖然XML一直是傳統的定義配置元數據的格式,但也能夠指示容器使用Java註解或者代碼做爲元數據的格式,並提供少許的XML配置以聲明的方式啓用這些額外的元數據格式的支持。spring
在大多數的應用場景,用戶代碼並不須要明確的實例化一個或多個Spring IoC容器的實例。例如,在web應用場景中,程序的web.xml文件中定義一個8行左右的web部署描述符XML就能夠知足要求。若是使用的是基於Eclipse的 Spring Tool Suite開發環境,該配置能夠很容易地用敲幾下鼠標或鍵盤建立。sql
下圖是展現 Spring 如何工做的高級視圖。應用程序的類與配置元數據進行結合,以便在 ApplicationContext建立和初始化後,擁有一個徹底配置和可執行的系統或應用程序。session
如上述圖所示,Spring IoC 容器使用配置元數據;這個配置元數據表明了應用程序開發人員告訴 Spring 容器在應用程序中如何來實例化,配置和組裝對象。架構
傳統的配置元數據是一個簡單而直觀的 XML 格式。框架
基於 XML 的元數據並非配置元數據的惟一容許的形式。 Spring IoC容器自己是徹底與配置元數據的實際寫入格式分離的。如今,許多開發人員選擇基於 Java 的配置來開發他們的應用程序。函數
其餘格式的元數據:ui
Spring 配置至少一個、一般不止一個 bean 由容器來管理。基於 XML 的配置元數據將這些 bean 配置爲<bean/>元素,並放置到<beans/> 元素內部。 Java 配置一般在 @Configuration註解的類中使用 @Bean 註解的方法。this
這些bean定義對應組成應用程序的實際對象。一般會定義服務層對象,數據訪問對象(DAO),展現對象,例如Structs Action實例,基礎設施的對象,如 Hibernate 的 SessionFactories,JMS Queues等等。一般,在容器中不配置細粒度的域對象,由於一般由DAO和業務邏輯負責建立和加載域對象(這裏的域對象應該相似於POJO)。可是你可使用 Spring 和 AspectJ的集成配置在 IoC 容器的控制以外建立的對象。url
如下示例顯示基於 XML 的配置元數據的基本結構:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="..." class="..."> <!-- collaborators and configuration for this bean go here --> </bean> <bean id="..." class="..."> <!-- collaborators and configuration for this bean go here --> </bean> <!-- more bean definitions go here --> </beans>
id 屬性是一個字符串,惟一識別一個獨立的 bean 定義。class 屬性定義了 bean 的類型,使用完整的類名。 id 屬性的值指向協做對象。在XML 配置協做對象未在本例中示給出(關於協做對象這句,應該是指在依賴關係的引用時使用id屬性,這個例子並無給出依賴關係的引用)。
實例化 Spring IoC 容器是簡單的。提供給ApplicationContext構造函數的位置路徑其實是容器從各類外部資源(如本地文件系統、Java ClassPath等)加載配置元數據的資源字符串。
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"});
當了解了Spring IoC容器後,由必要了解Spring Resource抽象概念,它提供了一種便捷的機制從uri語法定義的位置讀取InputStream。一般,Resource路徑用於構造應用上下文。
下面的例子展現了業務層對象(services.xml)的配置文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- services --> <bean id="petStore" class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl"> <property name="accountDao" ref="accountDao"/> <property name="itemDao" ref="itemDao"/> <!-- additional collaborators and configuration for this bean go here --> </bean> <!-- more bean definitions for services go here --> </beans>
下面的例子展現數據接入層(daos.xml)的配置文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="accountDao" class="org.springframework.samples.jpetstore.dao.jpa.JpaAccountDao"> <!-- additional collaborators and configuration for this bean go here --> </bean> <bean id="itemDao" class="org.springframework.samples.jpetstore.dao.jpa.JpaItemDao"> <!-- additional collaborators and configuration for this bean go here --> </bean> <!-- more bean definitions for data access objects go here --> </beans>
上面的例子中,業務層包含了PetStoreServiceImpl類和兩個類型爲JpaAccountDao和JpaItemDao數據接入對象(基於JPA對象/關係映射標準)。property元素的 name 屬性是指 JavaBean 屬性的名稱,而 ref 屬性引用另外一個 bean 定義的名稱。 id 和 ref 元素之間的這種聯繫表達了協做對象之間的依賴關係。
bean的定義跨越多個XML文件是有用的。通常一個XML配置文件表明程序架構中的一個業務層或業務模塊。
可使用應用上下文的構造函數從全部XML段中加載bean定義。構造函數加載多個Resource地址,正如上文的例子那樣。另外一種方法,可使用一個或多個<import/>元素從其它文件中加載bean定義。例如:
<beans> <import resource="services.xml"/> <import resource="resources/messageSource.xml"/> <import resource="/resources/themeSource.xml"/> <bean id="bean1" class="..."/> <bean id="bean2" class="..."/> </beans>
上例中,從三個文件中加載外部的bean定義:services.xml,messageSource.xml和themeSource.xml。全部的位置路徑都相對於導入文件的路徑,所以services.xml必須位於導入它的文件的相同文件夾或類路徑,而messageSource.xml和themeSource.xml需位於導入它們的文件路徑的resources下。前面的斜線能夠被忽略,但考慮到這些路徑是相對的,最好不使用斜線。被導入的文件(要包含頂級元素<beans/>),必須是有效的bean定義(根據Spring Schema)。
使用相對路徑../是可行的,可是並不推薦。這樣作會對當前應用程序以外的文件產生依賴。通常狀況下,這種相對路徑並不推薦用於classpach:URLs的格式(例如,classpath: ../services.xml),運行時解析進程選擇最近的classpath根目錄而後查找它的父文件夾。classpath配置改變也許會致使選擇了一個不一樣的、錯誤的文件夾。
應該老是使用絕對路徑代替相對路徑:例如"file:C:/config/services.xml"或者"classpath:/config/services.xml"。然而,應當注意這樣應用程序就和特定的絕對路徑耦合了。因此一般使用間接的方式應對這種絕對路徑,例如使用在JVM系統運行時解析的佔位符${...}。
XML文件中的import指令是由beans的命名空間自己提供的功能。不在beans命名空間中的更多配置功能由Spring的可選命名空間提供,例如context和util命名空間。
做爲外部配置元數據的進一步例子,bean定義可使用Spring的Groovy Bean Definition DSL(來自Grails框架)表示。通常的,這種配置保存在.groovy文件中並有以下的格式:
beans { dataSource(BasicDataSource) { driverClassName = "org.hsqldb.jdbcDriver" url = "jdbc:hsqldb:mem:grailsDB" username = "sa" password = "" settings = [mynew:"setting"] } sessionFactory(SessionFactory) { dataSource = dataSource } myService(MyService) { nestedBean = { AnotherBean bean -> dataSource = dataSource } } }
這種配置風格在很大程度上等同於XML bean定義,甚至支持Spring XML配置的命名空間。它還容許經過「importBeans」指令導入XML bean定義文件。
ApplicationContext是擁有註冊不一樣bean和它們之間依賴關係的高級工廠接口。使用方法 T getBean(String name, Class requiredType)就能夠獲取 bean 的實例。
ApplicationContext可使你按以下方法讀取bean定義並獲取它們:
// create and configure beans ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml"); // retrieve configured instance PetStoreService service = context.getBean("petStore", PetStoreService.class); // use configured instance List<String> userList = service.getUsernameList();
使用Groovy配置的啓動方式相似,僅僅是使用理解Groovy的context實現類(這個類依然可以識別XML的bean定義):
ApplicationContext context = new GenericGroovyApplicationContext("services.groovy", "daos.groovy");
最靈活的方式是將GenericApplicationContext類與reader代理一塊兒使用,例如讀取XML文件的XmlBeanDefinitionReader:
GenericApplicationContext context = new GenericApplicationContext(); new XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml", "daos.xml"); context.refresh();
或者讀取Groovy文件的GroovyBeanDefinitionReader:
GenericApplicationContext context = new GenericApplicationContext(); new GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy", "daos.groovy"); context.refresh();
若是須要這些reader代理能夠和同一ApplicationContext混合使用,從不一樣的配置源讀取bean定義。
可使用 getBean() 方法來獲取 bean 的實例。 ApplicationContext 接口有一些其餘的方法來獲取 bean,但理想的應用程序代碼不該該使用它們。事實上,你的應用程序代碼不該該調用的getBean() 方法,所以不會產生對 Spring 的 API 依賴性的。例如,Spring與web框架集成,爲web框架組件例如(controllers、JSF管理bean)提供依賴注入,容許你經過元數據爲特殊的bean聲明依賴關係。