Spring 官方中文文件--第1.2章節
文件是對照spring官方文件進行翻譯,都是本人親自翻譯,內容逐字逐句的進行推敲,不同與翻譯器的整篇翻譯(現有的多數中文文件都是靠翻譯器整篇翻譯,有很多內容並不能準確表達),應該是目前最好的官方中文文件。
翻譯不易,轉載請標明出處,尊重原創,從你我做起。
目錄
1.2.2 Instantiating a Container
Composing XML-based Configuration Metadata
The Groovy Bean Definition DSL
1.2 Container Overview
org.springframework.context.ApplicationContext
介面代表 Spring IoC 容器,並負責例項化,配置和組裝Bean。容器通過讀取配置元資料來獲取有關要例項化,配置和組裝哪些物件的指令。配置元資料以 XML,Java 註解或 Java 程式碼來描述。它使您能夠表達組成應用程式的物件以及這些物件之間的豐富相互依賴關係。
Spring 提供了 ApplicationContext 介面的幾種實現。在獨立應用程式中,通常建立ClassPathXmlApplicationContext或FileSystemXmlApplicationContext的例項。儘管 XML 是定義 配置元資料的傳統格式,但是您可以通過提供少量 XML 配置來宣告性地啟用對這些其他元資料格式 的支援,從而指示容器將 Java註釋或程式碼用作元資料格式。
在大多數應用場景中,不需要例項化使用者程式碼即可例項化一個 Spring IoC 容器的一個或多個例項。 例如,在 Web 應用程式場景中,應用程式 web.xml 檔案中的簡單八行(大約)樣板Web描述XML 通常就足夠了(請參閱Web 應用程式的便捷 ApplicationContext 例項化)。如果使用Spring工具套件(基於 Eclipse 的開發環境),則只需單擊幾次滑鼠或擊鍵即可輕鬆建立此樣板配置。
下圖顯示了 Spring 的工作原理的高階檢視。您的應用程式類與配置元資料結合在一起,以便在建立 和初始化 ApplicationContext 之後,您將具有完全配置且可執行的系統或應用程式。
圖 1. Spring IoC 容器
1.2.1 Configuration Metadata
如上圖所示,Spring IoC 容器使用一種形式的配置元資料。此配置元資料表示您作為應用程式開發 人員如何告訴 Spring 容器例項化,配置和組裝應用程式中的物件。
傳統上,配置元資料以簡單直觀的 XML 格式提供,這是本章大部分內容用來傳達 Spring IoC 容器 的關鍵概念和功能的內容。
基於 XML 的元資料不是配置元資料的唯一允許形式。 Spring IoC 容器本身與實際寫入此配 置元資料的格式完全脫鉤。如今,許多開發人員為自己的 Spring 應用程式選擇Java-based configuration。
有關在 Spring 容器中使用其他形式的元資料的資訊,請參見:
- Annotation-based configuration:spring2.5引入了基於註釋的配置元資料的支援
- Annotation-based configuration:從Spring3.0開始,SpringConfig專案提供的很多功能都成為了Spring Framework的核心內容的一部分。因此,您可以使用Java而不是XML檔案在應用程式類的外部定義bean。要使用這些新特性,請參閱
@Configuration
、@Bean
、@Import
和@DependsOn
註釋
Spring配置由容器必須管理的至少一個bean定義(通常是多個bean定義)組成。XML是通過在頂級元素中的元素來配置元資料。Java是通過在一個@Configuration
類中標記@Bean
來配置元資料。
這些 bean 定義對應於組成應用程式的實際物件。通常,您定義服務層物件,資料訪問物件(DAO),表示物件(例如 Struts Action 例項),基礎結構物件(例如 Hibernate SessionFactories,JMS Queues 等)。通常,不會在容器中配置細粒度的域物件,因為 DAO 和業務邏輯通常負責建立和載入域物件。但是,您可以使用 Spring 與 AspectJ 的整合來配置在 IoC 容器的控制範圍之外建立的物件。參考Using AspectJ to dependency-inject domain objects with Spring。
以下示例顯示了基於 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
https://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。有關更多資訊,請參見Dependencies。
1.2.2 Instantiating a Container
通過給ApplicationContext構造器提供一個資源位置的字串來使得容器從外部的資原始檔載入配置化的元資料。例如本地檔案系統,類路徑或者其他。
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
瞭解了 Spring 的 IoC 容器之後,您可能想了解更多有關 Spring 的 Resource 抽象(如Resources中所述),該抽象為從 URI 語法中定義的位置讀取 InputStream 提供了一種方便的機制。特別是, Resource 路徑用於構建應用程式上下文,如Application Contexts and Resource Pathss所述。
下面是service.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
https://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>
下面是dao.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
https://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 元素之間的這種 聯絡表達了協作物件之間的依賴性。有關配置物件的依賴項的詳細資訊,請參見:Dependencies
Composing XML-based Configuration Metadata
跨越多個xml檔案來定義bean是很有用的。通常一個單獨xml配置檔案代表一個邏輯層或者是你架構中的一個模組。
你可以通過應用上下文的構造器從這些所有的xml片段中載入對bean的定義。這個構造器可以有多個Resource路徑字串,就像前面案例所示。或者多次使用元素來從別的檔案載入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定義都是從service.xml、messageSource.xml和themeSource.xml三個檔案。所有的位置路徑都是相對於引進的那個檔案,所以service.xml必須於引入的檔案相同目錄或者位置路徑一樣。而messageSource.xml和messageSource.xml必須是位於引入檔案目錄下的resouce目錄下。正如你所看見的,前面的"/"符號被省略了。然而,考慮到這些路徑是相對的,最好完全不使用斜槓。根據Spring模式,被匯入的檔案的內容,包括頂層的元素,必須是有效的XML bean定義。
可以使用相對的".. "來引用父目錄中的檔案,但不建議這樣做。/”路徑。這樣做會在當前應用程式之外的檔案上建立一個依賴項。特別地,不建議對classpath: url(例如,classpath:../services.xml)引用此引用,在這種情況下,執行時解析過程會選擇“最近的”類路徑根,然後檢視它的父目錄。類路徑配置的更改可能會導致選擇一個不同的、錯誤的目錄。
您總是可以使用完全限定的資源位置而不是相對路徑:例如,file:C:/config/services.xml或classpath:/config/services.xml。但是,請注意您是將應用程式的配置耦合到特定的絕對位置。一般來說,最好為這樣的絕對位置保留一個間導性——例如,通過“${…}”佔位符在執行時根據JVM系統屬性解析佔位符。
名稱空間本身提供匯入指令特性。除了純bean定義之外,Spring提供的XML名稱空間還提供了更多的配置特性—例如,context
和util
名稱空間。
The Groovy Bean Definition DSL
作為外部化配置元資料的進一步示例,bean定義也可以用Spring的Groovy bean定義DSL表示,即Grails框架所知的DSL。通常,這樣的配置存在於'。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配置名稱空間。它同樣支援使用improtBeans的命令來引入xml的bean 定義元資料。
1.2.3 Using the Container
ApplicationContext
是一個具有對所註冊的不同bean和它們所依賴的bean更好維護能力的先進的工廠的介面。使用T getBean(String name, Class<T> requiredType)
方法來檢索你的beans。
ApplicationContext
允許你讀取和訪問bean definitions,想下面這樣:
// 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(但也理解XML bean定義)。下面的例子展示了Groovy的配置:
ApplicationContext context = new GenericGroovyApplicationContext("services.groovy", "daos.groovy");
最靈活的變體是GenericApplicationContext
與閱讀器委託的結合——例如,針對XML檔案的XmlBeanDefinitionReader
,如下面的例子所示:
GenericApplicationContext context = new GenericApplicationContext();
new XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml", "daos.xml");
context.refresh();
你也可以使用GroovyBeanDefinitionReader
來讀取Groovy檔案,例如下面:
GenericApplicationContext context = new GenericApplicationContext();
new GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy", "daos.groovy");
context.refresh();
你可以在同一個ApplicationContext中混合使用閱讀器委託,來從不同的資源位置讀取bean definition。
你可以使用getBean()方法獲取你的bean例項,ApplicationContext
中有很多方法獲取bean,但是聰明的話,最好不要使用它們。實際上,您的應用程式程式碼根本不應該呼叫getBean()方法,因此根本不依賴於Spring api。例如Spring與web框架整合提供了通過依賴注入web框架元件的變體,比方說Controller和Jsf-manager。讓你可以在一個bean上通過元資料(例如自動裝配註釋@Autowried)來宣告依賴。