????? 配置文件的根元素是beans,每個組件使用bean元素來定義,bean元素可以有許多屬性,其中有兩個是必須的:id和class(這里說的id是必須的并不意味著在配置文件中必須指定id,后面會詳細說明)。id表示組件的默認名稱,class表示組件的類型。
????? 如果使用設值注入,則需要使用property子標簽,來指定組件的屬性。
<bean id="renderer" class="com.apress.prospring.ch2.StandardOutMessageRenderer">
??? <property name="messageProvider">
??????? <ref local="provider"/>
??? </property>
</bean>
?????
使用構造子注入時,則使用constructor-arg子標簽,來指定構造函數的參數。
<bean id="provider" class="com.apress.prospring.ch4.ConfigurableMessageProvider">
??? <constructor-arg>
??????? <value>This is a configurable message</value>
??? </constructor-arg>
</bean>
?????
當構造函數有多個參數時,可以使用constructor-arg標簽的index屬性,index屬性的值從0開始。
<bean id="provider" class="com.apress.prospring.ch4.ConfigurableMessageProvider">
??? <constructor-arg index="0">
??????? <value>first parameter</value>
??? </constructor-arg>
??? <constructor-arg index="1">
??????? <value>second parameter</value>
??? </constructor-arg>
</bean>
???? 在使用構造子注入時,需要注意的問題是要避免構造子沖突的情況發生。考慮下面的情況:
public class ConstructorConfusion {
??? public ConstructorConfusion(String someValue) {
??????? System.out.println("ConstructorConfusion(String) called");
??? }
??? public ConstructorConfusion(int someValue) {
??????? System.out.println("ConstructorConfusion(int) called");
??? }
}
????
使用如下配置文件
<bean id="constructorConfusion" class="com.apress.prospring.ch4.ConstructorConfusion">
??? <constructor-arg>
??????? <value>90</value>
??? </constructor-arg>
</bean>
???? 那么,當實例化組件constructorConfusion時,將輸出ConstructorConfusion(String) called,也就是說參數類型為String的構造函數被調用了,這顯然不符合我們的要求。為了讓Spring調用參數為int的構造函數來實例化組件constructorConfusion,我們需要在配置文件中明確的告訴Spring,需要使用哪個構造函數,這需要使用constructor-arg的type屬性。
<bean id="constructorConfusion" class="com.apress.prospring.ch4.ConstructorConfusion">
??? <constructor-arg type="int">
??????? <value>90</value>
??? </constructor-arg>
</bean>
???? 我們不僅可以構造單個BeanFactory,而且可以建立有繼承關系的多個BeanFactory。只需要將父BeanFactory作為參數傳給子BeanFactory的構造函數即可。
BeanFactory parent =
??? new XmlBeanFactory(new FileSystemResource("./ch4/src/conf/parent.xml"));
BeanFactory child =
??? new XmlBeanFactory(new FileSystemResource("./ch4/src/conf/beans.xml"), parent);
???? 如果子BeanFactory和父BeanFactory中含有名稱相同的Bean,那么在子BeanFactory中使用
<ref bean="sameNameBean"/>引用的將是子BeanFactory中的bean,為了引用父BeanFactory中的bean,我們需要使用ref標簽的parent屬性,<ref parent="sameNameBean"/>。
???? 為了注入集合屬性,Spring提供了list,map,set和props標簽,分別對應List,Map,Set和Properties,我們甚至可以嵌套的使用它們(List of Maps of Sets of Lists)。
<bean id="injectCollection" class="com.apress.prospring.ch4.CollectionInjection">
??? <property name="map">
??????? <map>
??????????? <entry key="someValue">
??????????????? <value>Hello World!</value>
??????????? </entry>
??????????? <entry key="someBean">
??????????????? <ref local="oracle"/>
????????????</entry>
??????? </map>
??? </property>
??? <property name="props">
??????? <props>
??????????? <prop key="firstName">
??????????????? Rob
??????????? </prop>
??????????? <prop key="secondName">
??????????????? Harrop
??????????? </prop>
??????? </props>
??? </property>
??? <property name="set">
??????? <set>
??????????? <value>Hello World!</value>
??????????? <ref local="oracle"/>
??????? </set>
??? </property>
??? <property name="list">
??????? <list>
??????????? <value>Hello World!</value>
??????????? <ref local="oracle"/>
????????</list>
??? </property>
</bean>