容器是Spring框架的核心。Spring容器使用IOC管理所有組成應(yīng)用系統(tǒng)的組件。這包括在協(xié)作組件之間建立關(guān)聯(lián)。Spring實(shí)際上有2種不同的容器:Bean工廠(org.springframewor.bens.factory.BeanFactory接口定義)是最簡(jiǎn)單的容器,提供了基礎(chǔ)的依賴注入支持。應(yīng)用上下文(由org.springframework.contextApplicationContext接口定義)建立在Bean工廠基礎(chǔ)之上,提供了系統(tǒng)架構(gòu)服務(wù)。
(1)、BeanFactory這個(gè)類負(fù)責(zé)創(chuàng)建和分發(fā)Bean.由于Bean工廠知道應(yīng)用系統(tǒng)中的很多對(duì)象,所以它可以在實(shí)例化這些對(duì)象的時(shí)候,創(chuàng)建協(xié)作對(duì)象間的關(guān)聯(lián)關(guān)系。這樣就把配置的負(fù)擔(dān)從Bean自身以及Bean的調(diào)用者中脫離出來(lái)。在Spring中有幾種BeanFactory的實(shí)現(xiàn)。其中最常使用的是org.springframework.beans.factory.xml.XmlBeanFactory,它根據(jù)XML文件中的定義裝載Bean.
例如:BeanFactory factory = new XmlBeanFactory(new FileInputStream("beans.xml"));
這行代碼告訴Bean工廠從XML文件中讀取Bean的定義信息。但是,現(xiàn)在Bean工廠還沒(méi)有實(shí)例化Bean.Bean是被延遲載入到Bean工廠中的,就是說(shuō)Bean工廠會(huì)立即把Bean定義信息載入進(jìn)來(lái),但是Bean只有在被需要的時(shí)候才被實(shí)例化。
MyBean myBean = (MyBean)factory.getBean("myBean");
當(dāng)getBean()方法被調(diào)用的時(shí)候,工廠就會(huì)實(shí)例化Bean并且使用依賴注入開始設(shè)置Bean的屬性。
(2)、ApplicationContext的諸多實(shí)現(xiàn)中,有3個(gè)實(shí)現(xiàn)經(jīng)常用到:
ClassPathXmlApplicationContext-從類路徑中的XML文件載入上下文定義信息,把上下文定義文件當(dāng)成類路徑資源。
FileSystemXmlApplicationContext-從文件系統(tǒng)中的XML文件載入上下文定義信息。
XmlWebApplicationContext-從web系統(tǒng)中的XML文件載入上下文定義信息。
例如:ApplicationContext context = new FileSystemXmlApplicationContext("c:/foo.xml");
ApplicationContext context = new ClassPathXmlApplicationContext("foo.xml");
FileSystemXmlApplicationContext只能在指定的路徑中尋找foo.xml文件,而ClassPathXmlApplicationContext可以在整個(gè)類路徑中尋找foo.xml.
應(yīng)用上下文與Bean工廠的另一個(gè)重要區(qū)別是關(guān)于單實(shí)例Bean是如何被載入的。Bean工廠延遲載入所有的Bean,知道getBean()方法被調(diào)用時(shí)Bean才被創(chuàng)建。應(yīng)用上下文啟動(dòng)后預(yù)載入所有的單實(shí)例Bean.
Spring中的Bean缺省情況下是單例模式。在容器分配Bean的時(shí)候,它總是返回同一個(gè)實(shí)例。如果想每次得到不同的實(shí)例你需要將Bean定義為原型模式。定義為原型模式意味著你是定義一個(gè)Bean藍(lán)圖,而不是一個(gè)單一的Bean.<bean>的singleton屬性告訴這個(gè)bean是否是單例的,如果是true表示是單例的,如果是false表示是原型的。
<bean id="connectionPool" class="com.springinaction.chapter02.MyConnectionPool" init-method="initialize" destroy-method="close"/>
按這樣配置,MyConnectionPool被實(shí)例化后initialize()方法馬上被調(diào)用,給Bean初始化池的機(jī)會(huì)。在Bean從容器中刪除之前,close()方法將釋放數(shù)據(jù)庫(kù)連接。
設(shè)值注入:它是一種基于標(biāo)準(zhǔn)命名規(guī)范的設(shè)置Bean屬性的技術(shù)。JavaBean規(guī)范規(guī)定使用對(duì)應(yīng)的set和get方法來(lái)設(shè)置和獲得Bean的屬性值。<property>元素的子元素<value>用來(lái)設(shè)置普通類型的屬性,子元素<ref bean="">用來(lái)設(shè)置要關(guān)聯(lián)的Bean.
內(nèi)部Bean:另一種不常使用的裝配Bean引用的方法是在<property>元素中嵌入一個(gè)<bean>元素。
<bean id="courseService" class="com.springinaction.service.training.CourseServiceImpl">
<property name="studentService">
<bean class="com.springinaction.service.training.StudentServiceImpl"/>
</property>
</bean>
<property name="studentService">
<bean class="com.springinaction.service.training.StudentServiceImpl"/>
</property>
</bean>
這種裝配Bean引用的方式的缺點(diǎn)是你無(wú)法在其他地方重用這個(gè)StudentServiceImpl實(shí)例,因?yàn)樗且粋€(gè)專門的courseServiceBean建立的實(shí)例。
注入的是對(duì)象集:如果你有一個(gè)屬性是一個(gè)列表或是一個(gè)Bean引用集合,Spring支持多種類型的集合作為屬性。
<list><set><map><props>
裝配List和數(shù)組:裝配一個(gè)List屬性,List里的元素可以是任何一種元素,包括<value><ref>甚至是其他<list>
<property name="barList">
<list>
<value>bar1</value>
<ref bean="bar2"/>
</list>
</property>
<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>
<value>bar1</value>
<ref bean="bar2"/>
</set>
</property>
<set>的使用方法和<list>是一樣的。唯一不同的地方是它被裝到什么樣的屬性中。<list>是向java.util.List或數(shù)組里裝配數(shù)據(jù),而<set>是向java.util.Set中裝配數(shù)據(jù)。
裝配Map:
<property name="barMap">
<map>
<entry key="key1">
<value>bar1</value>
</entry>
<entry key="key2">
<value>bar2</value>
</entry>
</map>
</property>
<map>
<entry key="key1">
<value>bar1</value>
</entry>
<entry key="key2">
<value>bar2</value>
</entry>
</map>
</property>
Map中的<entry>的數(shù)值和<list>以及<set>的一樣,可以是任何有效的屬性元素。重申一邊,包括<value>、<ref>、<list>甚至是另一個(gè)<map>。注意,配置<entry>時(shí),屬性key的值只能是String.這對(duì)于java.util.Map的功能來(lái)說(shuō)有一點(diǎn)限制,java.util.Map是允許任何類型的對(duì)象作為主鍵的。
裝配properties:java.util.Properties集合是最后一個(gè)能在Spring中裝配的集合類。使用<props>元素來(lái)裝配它。使用<prop>元素表示每條屬性。
<property name="barProps">
<props>
<prop key="key1">bar1</prop>
<prop key="key2">bar2</prop>
</props>
</property>
<props>
<prop key="key1">bar1</prop>
<prop key="key2">bar2</prop>
</props>
</property>
設(shè)置null
為了將一個(gè)屬性設(shè)為null,你只要使用<null/>元素就行了。
例如:
<property name="foo"><null/><property>