傳統建立應用系統對象之間關聯關系的方法會導致復雜的代碼,使它們很難被服用,很難做單元測試。在Spring中,組件無需自己負責與其他組件的關聯。取而代之的是,容器負責把協作左鍵的引用給予各個組件。創建系統組件之間協作關系的這個動作叫做裝配。
容器是Spring框架的核心。Spring容器使用IOC管理所有組成應用系統的組件。這包括在協作組件之間建立關聯。Spring實際上有2種不同的容器:Bean工廠(org.springframewor.bens.factory.BeanFactory接口定義)是最簡單的容器,提供了基礎的依賴注入支持。應用上下文(由org.springframework.contextApplicationContext接口定義)建立在Bean工廠基礎之上,提供了系統架構服務。
(1)、BeanFactory這個類負責創建和分發Bean.由于Bean工廠知道應用系統中的很多對象,所以它可以在實例化這些對象的時候,創建協作對象間的關聯關系。這樣就把配置的負擔從Bean自身以及Bean的調用者中脫離出來。在Spring中有幾種BeanFactory的實現。其中最常使用的是org.springframework.beans.factory.xml.XmlBeanFactory,它根據XML文件中的定義裝載Bean.
例如:BeanFactory factory = new XmlBeanFactory(new FileInputStream("beans.xml"));
這行代碼告訴Bean工廠從XML文件中讀取Bean的定義信息。但是,現在Bean工廠還沒有實例化Bean.Bean是被延遲載入到Bean工廠中的,就是說Bean工廠會立即把Bean定義信息載入進來,但是Bean只有在被需要的時候才被實例化。
MyBean myBean = (MyBean)factory.getBean("myBean");
當getBean()方法被調用的時候,工廠就會實例化Bean并且使用依賴注入開始設置Bean的屬性。
(2)、ApplicationContext的諸多實現中,有3個實現經常用到:
ClassPathXmlApplicationContext-從類路徑中的XML文件載入上下文定義信息,把上下文定義文件當成類路徑資源。
FileSystemXmlApplicationContext-從文件系統中的XML文件載入上下文定義信息。
XmlWebApplicationContext-從web系統中的XML文件載入上下文定義信息。
例如:ApplicationContext context = new FileSystemXmlApplicationContext("c:/foo.xml");
ApplicationContext context = new ClassPathXmlApplicationContext("foo.xml");
FileSystemXmlApplicationContext只能在指定的路徑中尋找foo.xml文件,而ClassPathXmlApplicationContext可以在整個類路徑中尋找foo.xml.
應用上下文與Bean工廠的另一個重要區別是關于單實例Bean是如何被載入的。Bean工廠延遲載入所有的Bean,知道getBean()方法被調用時Bean才被創建。應用上下文啟動后預載入所有的單實例Bean.
Spring中的Bean缺省情況下是單例模式。在容器分配Bean的時候,它總是返回同一個實例。如果想每次得到不同的實例你需要將Bean定義為原型模式。定義為原型模式意味著你是定義一個Bean藍圖,而不是一個單一的Bean.<bean>的singleton屬性告訴這個bean是否是單例的,如果是true表示是單例的,如果是false表示是原型的。
<bean id="connectionPool" class="com.springinaction.chapter02.MyConnectionPool" init-method="initialize" destroy-method="close"/>
按這樣配置,MyConnectionPool被實例化后initialize()方法馬上被調用,給Bean初始化池的機會。在Bean從容器中刪除之前,close()方法將釋放數據庫連接。
設值注入:它是一種基于標準命名規范的設置Bean屬性的技術。JavaBean規范規定使用對應的set和get方法來設置和獲得Bean的屬性值。<property>元素的子元素<value>用來設置普通類型的屬性,子元素<ref bean="">用來設置要關聯的Bean.
內部Bean:另一種不常使用的裝配Bean引用的方法是在<property>元素中嵌入一個<bean>元素。
<bean id="courseService" class="com.springinaction.service.training.CourseServiceImpl">
<property name="studentService">
<bean class="com.springinaction.service.training.StudentServiceImpl"/>
</property>
</bean>
這種裝配Bean引用的方式的缺點是你無法在其他地方重用這個StudentServiceImpl實例,因為它是一個專門的courseServiceBean建立的實例。
注入的是對象集:如果你有一個屬性是一個列表或是一個Bean引用集合,Spring支持多種類型的集合作為屬性。
<list><set><map><props>
裝配List和數組:裝配一個List屬性,List里的元素可以是任何一種元素,包括<value><ref>甚至是其他<list>
<property name="barList">
<list>
<value>bar1</value>
<ref bean="bar2"/>
</list>
</property>
裝配Set:和List一樣,Set可以包含任何類型的屬性。
<property name="barSet">
<set>
<value>bar1</value>
<ref bean="bar2"/>
</set>
</property>
<set>的使用方法和<list>是一樣的。唯一不同的地方是它被裝到什么樣的屬性中。<list>是向java.util.List或數組里裝配數據,而<set>是向java.util.Set中裝配數據。
裝配Map:
<property name="barMap">
<map>
<entry key="key1">
<value>bar1</value>
</entry>
<entry key="key2">
<value>bar2</value>
</entry>
</map>
</property>
Map中的<entry>的數值和<list>以及<set>的一樣,可以是任何有效的屬性元素。重申一邊,包括<value>、<ref>、<list>甚至是另一個<map>。注意,配置<entry>時,屬性key的值只能是String.這對于java.util.Map的功能來說有一點限制,java.util.Map是允許任何類型的對象作為主鍵的。
裝配properties:java.util.Properties集合是最后一個能在Spring中裝配的集合類。使用<props>元素來裝配它。使用<prop>元素表示每條屬性。
<property name="barProps">
<props>
<prop key="key1">bar1</prop>
<prop key="key2">bar2</prop>
</props>
</property>
設置null
為了將一個屬性設為null,你只要使用<null/>元素就行了。
例如:
<property name="foo"><null/><property>
posted on 2009-10-29 10:28
王永慶 閱讀(1598)
評論(2) 編輯 收藏 所屬分類:
SPRING