依賴注入方式:Spring支援兩種依賴注入方式,分别是屬性注入和構造函數注入。還有工廠方法注入方式。
依賴注入還分為:注入依賴對象可以采用手工裝配或自動裝配,在實際應用開發中建議使用手工裝配,因為自動裝配會産生許多未知情況,開發人員無法預見最終的裝配結果。
手工裝配依賴對象又分為3種方式:
1、程式設計方式(寫的過程中向BeanFactory去注冊)
2、是在XML檔案中,通過在bean節點下配置;如上面講到的使用屬性的setter方法注入依賴對象和使用構造器方法注入依賴對象都是這種方式。
3、就是在java代碼中使用注解的方式進行裝配,在代碼中加入@Resource或者@Autowired等,怎樣使用注解的方式來為某個bena注入依賴對象呢?
自動裝配依賴對象分為2種方式:
1、配置檔案的bean中增加autowire
2、也可以選擇在beans中加入default-autowire屬性,為所有bean設定預設自動裝配
Spring中提供了自動裝配依賴對象的機制,但是在實際應用中并不推薦使用自動裝配,因為自動裝配會産生未知情況,開發人員無法預見最終的裝配結果。
自動裝配是在配置檔案中實作的,如下:
<bean id="***" class="***" autowire="byType">
隻需要配置一個autowire屬性即可完成自動裝配,不用再配置檔案中寫<property>,但是在類中還是要生成依賴對象的setter方法。
Autowire的屬性值有如下幾個:
· byType 按類型裝配 可以根據屬性類型,在容器中尋找該類型比對的bean,如有多個,則會抛出異常,如果沒有找到,則屬性值為null;
· byName 按名稱裝配 可以根據屬性的名稱在容器中查詢與該屬性名稱相同的bean,如果沒有找到,則屬性值為null;
· constructor 與byType方式相似,不同之處在與它應用于構造器參數,如果在容器中沒有找到與構造器參數類型一緻的bean,那麼将抛出異常;
· autodetect 通過bean類的自省機制(introspection)來決定是使用constructor還是byType的方式進行自動裝配。如果發現預設的構造器,那麼将使用byType的方式。
---------------分割線-----------------------------------------------------------------------------------------------------
示例:
一、使用屬性setter方法注入
下面是Bean和beans-config.xml檔案。
xml檔案:
java:
二、使用constructor方式完成注入
其中xml配置有如下方式:
在配置檔案中配置該類的bean,并配置構造器,在配置構造器中用到了<constructor-arg>節點,該節點有四個屬性:
· index是索引,指定注入的屬性,從0開始,如:0代表personDao,1代表str屬性;
· type是指該屬性所對應的類型,如Persondao對應的是com.aptech.dao.PersonDAO;
· ref 是指引用的依賴對象;
· value 當注入的不是依賴對象,而是基本資料類型時,就用value;
java代碼:
java代碼:
三、屬性參考
public class HelloBean {
private String helloWord;
private Date date;
//...省略getter、setter方法
}
<beans>
<bean id="dateBean" class="java.util.Date"/>
<bean id="helloBean" class="onlyfun.caterpillar.HelloBean">
<property name="helloWord">
<value>Hello!</value>
</property>
<property name="date">
<ref bean="dateBean"/>
</bean>
</beans>
public class SpringDemo {
public static void main(String[] args) {
ApplicationContext context =
new FileSystemXmlApplicationContext("beans-config.xml");
HelloBean hello = (HelloBean) context.getBean("helloBean");
System.out.print(hello.getHelloWord());
System.out.print(" It's ");
System.out.print(hello.getDate());
System.out.println(".");
}
四、“byType”自動綁定
将“三”中的配置檔案改為下面,即可完成bean屬性的按類型自動綁定。
<bean id="helloBean" class="onlyfun.caterpillar.HelloBean" autowire="byType">
五、“byName”自動綁定
将“三”中的配置檔案改為下面,即可完成bean屬性的按名稱自動綁定。
<bean id="helloBean" class="onlyfun.caterpillar.HelloBean" autowire="byName">
六、“constructor”自動綁定
将“三”中的配置檔案改為下面,即可完成bean屬性的按構造方法自動綁定。在建立依賴關系時,Srping容器會試圖比對容器中的Bean執行個體類型,及相關的構造方法上的參數類型,看看在類型上是否符合,如果有的話,則選用該構造方法來建立Bean執行個體。如果無法綁定,則抛出org.springframework.beans.factory.UnsatisfiedDependencyException異常。
<bean id="helloBean" class="onlyfun.caterpillar.HelloBean" autowire="constructor">
七、“autodetect”自動綁定
将“三”中的配置檔案改為下面,即可完成bean屬性的自動綁定,這個自動綁定是Spring會嘗試用入constructor來處理依賴關系的建立,如果不行,則再嘗試用byType類建立依賴關系。
<bean id="helloBean" class="onlyfun.caterpillar.HelloBean" autowire="autodetect">
八、依賴檢查方式
在自動綁定中,由于沒辦法從定義檔案中,清楚地看到是否每個屬性都完成設定,為了确定某些依賴關系确實建立,您可以假如依賴檢查,在<bean>标簽使用時設定"dependency-check",可以有四種依賴檢查方式:simple、objects、all、none。
simple:隻檢查簡單的類型(像原生資料類型或字元串對象)屬性是否完成依賴關系,。
objects:檢查對象類型的屬性是否完成依賴關系。
all:則檢查全部的屬性是否完成依賴關系。
none:設定是預設值,表示不檢查依賴性。
<bean id="helloBean" class="onlyfun.caterpillar.HelloBean" autowire="autodetect" dependeny-check="all">
九、集合對象注入
對于像數組、List、Set、Map等集合對象,在注入前必須填充一些對象至集合中,然後再将集合對象注入至所需的Bean時,也可以交由Spring的IoC容器來自動維護或生成集合對象,并完成依賴注入。
public class SomeBean {
private String[] someStrArray;
private Some[] someObjArray;
private List someList;
private Map someMap;
public String[] getSomeStrArray() {
return someStrArray;
}
public void setSomeStrArray(String[] someStrArray) {
this.someStrArray = someStrArray;
public Some[] getSomeObjArray() {
return someObjArray;
public void setSomeObjArray(Some[] someObjArray) {
this.someObjArray = someObjArray;
public List getSomeList() {
return someList;
public void setSomeList(List someList) {
this.someList = someList;
public Map getSomeMap() {
return someMap;
public void setSomeMap(Map someMap) {
this.someMap = someMap;
public class Some {
private String name;
public String getName() {
return name;
public void setName(String name) {
this.name = name;
public String toString() {
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="some1" class="onlyfun.caterpillar.Some">
<property name="name">
<value>Justin</value>
</property>
</bean>
<bean id="some2" class="onlyfun.caterpillar.Some">
<value>momor</value>
<bean id="someBean" class="onlyfun.caterpillar.SomeBean">
<property name="someStrArray">
<list>
<value>Hello</value>
<value>Welcome</value>
</list>
<property name="someObjArray">
<ref bean="some1"/>
<ref bean="some2"/>
<property name="someList">
<value>ListTest</value>
<property name="someMap">
<map>
<entry key="MapTest">
<value>Hello!Justin!</value>
</entry>
<entry key="someKey1">
<ref bean="some1"/>
</map>
new FileSystemXmlApplicationContext(
"beans-config.xml");
SomeBean someBean =
(SomeBean) context.getBean("someBean");
// 取得數組型态依賴注入對象
String[] strs =
(String[]) someBean.getSomeStrArray();
Some[] somes =
(Some[]) someBean.getSomeObjArray();
for(int i = 0; i < strs.length; i++) {
System.out.println(strs[i] + ","
+ somes[i].getName());
}
// 取得List型态依賴注入對象
System.out.println();
List someList = (List) someBean.getSomeList();
for(int i = 0; i < someList.size(); i++) {
System.out.println(someList.get(i));
// 取得Map型态依賴注入對象
Map someMap = (Map) someBean.getSomeMap();
System.out.println(someMap.get("MapTest"));
System.out.println(someMap.get("someKey1"));
十、靜态工廠的方法注入
靜态工廠顧名思義,就是通過調用靜态工廠的方法來擷取自己需要的對象,為了讓spring管理所有對象,我們不能直接通過"工程類.靜态方法()"來擷取對象,而是依然通過spring注入的形式擷取:
Java代碼
同樣看關鍵類,這裡我需要注入一個FactoryDao對象,這裡看起來跟第一種注入一模一樣,但是看随後的xml會發現有很大差别:
Java代碼
Spring的IOC配置檔案,注意看<bean name="staticFactoryDao">指向的class并不是FactoryDao的實作類,而是指向靜态工廠DaoFactory,并且配置 factory-method="getStaticFactoryDaoImpl"指定調用哪個工廠方法:
Xml代碼
十一、執行個體工廠的方法注入
執行個體工廠的意思是擷取對象執行個體的方法不是靜态的,是以你需要首先new工廠類,再調用普通的執行個體方法:
那麼下面這個類沒什麼說的,跟前面也很相似,但是我們需要通過執行個體工廠類建立FactoryDao對象:
最後看spring配置檔案: