本文中主要包含下面的幾個內容:
7.何時使用singleton
bean的三種裝配方式、8.設置bean的屬性和協作者
9.bean構造函數選擇決議
10.自動裝配
Java bean,11.依賴檢查
7.何時使用singleton
如果bean使用的是singleton的話,那么通過getBean得到的始終是一個對象,如果使用的是prototype的話,那么每次spring會重新new一個新的對象。下面是測試的代碼片段:
@bean?<bean id="singletoninstance" class="singletonornot.POJO" abstract="false" scope="singleton" lazy-init="default" autowire="default" > </bean> <bean id="prototypeinstance" class="singletonornot.POJO" abstract="false" scope="prototype" lazy-init="default" autowire="default" > </bean>
POJO p1 = (POJO)context.getBean("singletoninstance"); POJO p2 = (POJO)context.getBean("singletoninstance"); if (p1 == p2) { System.out.println("p1 and p2 are the same"); } POJO p3 = (POJO)context.getBean("prototypeinstance"); POJO p4 = (POJO)context.getBean("prototypeinstance"); if (p3 == p4) { System.out.println("p1 and p2 are the same"); }
8.設置bean的屬性和協作者
Spring Framework、在spring中反轉控制和依賴注入大致上通過兩種方法實現:
1.通過set屬性實現
2.通過類的構造函數實現
Spring boot?下面是一個簡單的通過set屬性實現的反轉控制和依賴注入的demo:
SetterBean.java
/** * */ package beanfactory.coredi; /** * @author jefferyxu * */ public class SetterBean { private AnotherBean beanOne; private YetAnotherBean beanTwo; private int i; public void setIntegerProperty(int i) { this.i = i; } /** * @return the beanOne */ public AnotherBean getBeanOne() { return beanOne; } /** * @param beanOne the beanOne to set */ public void setBeanOne(AnotherBean beanOne) { this.beanOne = beanOne; } /** * @return the beanTwo */ public YetAnotherBean getBeanTwo() { return beanTwo; } /** * @param beanTwo the beanTwo to set */ public void setBeanTwo(YetAnotherBean beanTwo) { this.beanTwo = beanTwo; } public String toString() { return "bean one :" + this.beanOne + " bean tow " + this.beanTwo + " integer property " + this.i; } }
通過這種方法生成的bean定義如下:
<bean id="setterBean" class="beanfactory.coredi.SetterBean" abstract="false" lazy-init="default" autowire="default" p:beanOne-ref="anotherBean" p:beanTwo-ref="yetAnotherBean" p:integerProperty="1"> </bean>
當然也可以這么寫:
<bean id="setterBean" class="beanfactory.coredi.SetterBean"> <property name="beanOne"> <ref bean="anotherBean"/> </property> <property name="beanTwo"> <ref bean="yetAnotherBean"/> </property> <!-- 注意這里填寫的name屬性需要和setterBean類中set 方法相對應,這里寫的是integerProperty,所以 需要 存在setIntegerProperty方法 --> <property name="integerProperty"> <value>1</value> </property> </bean>
這里需要特別注意的是需要property的name屬性需要和類中的set方法相對應。
2.通過構造函數實現反轉控制和依賴注入簡單demo:
ConstructorBean.java :
/** * */ package beanfactory.coredi; /** * @author jefferyxu * */ public class ConstructorBean { private AnotherBean beanOne; private YetAnotherBean beanTwo; private int i; public ConstructorBean(AnotherBean one, YetAnotherBean two, int i) { this.beanOne = one; this.beanTwo = two; this.i = i; } public String toString(){ return "bean one :" + this.beanOne + " bean tow " + this.beanTwo + " integer property " + this.i; } }
applicationContext.xml :
<bean id="contructorBean" class="beanfactory.coredi.ConstructorBean"> <!-- 注意這里參數的順序沒有必要 按照構造函數中的順序 --> <constructor-arg> <ref bean="yetAnotherBean"/> </constructor-arg> <constructor-arg> <ref bean="anotherBean"/> </constructor-arg> <constructor-arg> <value>1</value> </constructor-arg> </bean>
需要注意的是通過構造函數實現依賴注入和反轉控制時,constructor-arg的順序沒有必要和類的構造函數的性質相一致。
9.bean構造函數選擇決議
bean構造函數選擇決議,及類似于函數重載時需要選擇那個函數。
這里需要注意的是兩個屬性:
1.constructor-arg的type屬性:默認的情況下,spring將<value>中的內容解析為string,所以在spring增加type屬性,顯示捆綁xxx類型。
2.constructor-arg的index屬性:index屬性用來索引各構造函數的參數的順序,從0開始。
例如如果將修改成這樣:
<constructor-arg index="0"> <value>1</value> </constructor-arg>
顯然這是錯的,于是產生如下的錯誤:
Unsatisfied dependency expressed through constructor argument with index 0 of type
10.自動裝配
自動裝配通過autowire屬性實現,主要是針對setter方式實現依賴注入和反轉控制的bean:
這里有兩個常見屬性:byType,byName,其中byType的話,spring會自動查找和set中同類型的bean。同理byName,是通過和類文件中屬性同名的bean相關聯。
11.依賴檢查
依賴檢查確保所有的或者是部分的bean屬性得到正確的設置。
其中object最常用,主要是對bean中被使用者進行檢查。