本文研究Spring的三種依賴注入實現類型——接口注入(Interface Injection)、設值注入(Setter Injection)、構造子注入(Constructor Injection)。
Type1
接口注入:
傳統的創建接口對象的方法,
借助接口來將調用者與實現者分離。如下面的代碼所示:
?1?public?class
?ClassA?
?2?
{
?3?private
?InterfaceB?clzB;
?4?public
?doSomething()?
?5?
{
?6?Ojbect?obj?=
?Class.forName(Config.BImplementation).newInstance();
?7?clzB?=
?(InterfaceB)obj;
?8?
clzB.doIt();
?9?
}
10?
……
11?
}
12?
在代碼中創建InterfaceB實現類的實例,并將該對象賦予clzB。也就是依據Java中的對象動態多態技術:InterfaceB clzB=new InterfaceBImpleClass();為了將調用者與實現者在編譯期分離,于是有了上面的代碼,我們根據預先在配置文件中設定的實現類的類名(Config.BImplementation),動態加載實現類,并通過InterfaceB強制轉型后為 ClassA所用。
Type2
設值注入:
在各種類型的依賴注入模式中,設值注入模式在實際開發中得到了最廣泛的應用(其中很大一部分得力于Spring框架的
影響)。使用IoC的Setter注射,一些外部元數據被用于解決依賴性問題。并且在Spring中,這種元數據采取了簡單的XML配置文件的形式。
?下面為某個類的示例代碼
?(其中包含有一個message屬性,該類通過其setMessage()方法獲得右容器所提供的值。)
?1?public?class?UpperAction??implements
?Action
?2?
{
?3???private
?String?message;
?4???public
?String?getMessage()?
?5?
??{
?6?????return
?message;
?7?
??}
?8???public?void
?setMessage(String?string)?
?9?
??{
10?????message?=
?string;
11?
??}
12?
}
13?
?
其中message
屬性的值通過配置文件來提供
1?<bean?id="theUpperAction"??class="springj2seapp.UpperAction">
2??????<property?name="message">
3?????????<value>HeLLo,UpperAction?</value>
4?????</property>
5?</bean>
6?
Type3
構造子注入:
在Type3類型的依賴注入機制中,依賴關系是通過類構造函數建立,容器通過調用類的構造方法,將其所需的依賴關系注入其中。
示例代碼:
配置文件如下
?1?<bean?id="exampleBean"?class="examples.ExampleBean">
?2?
?3???<constructor-arg>
?4?
?5?<ref?bean="anotherExampleBean"/>
?6?</constructor-arg>
?7???<constructor-arg><ref?bean="yetAnotherBean"/></constructor-arg>
?8???<constructor-arg?type="int">
?9?<value>1</value>
10?</constructor-arg>
11?</bean>
12?<bean?id="anotherExampleBean"?class="examples.AnotherBean"/>
13?<bean?id="yetAnotherBean"?class="examples.YetAnotherBean"/>
14?
ExampleBean代碼:
?1?public?class
?ExampleBean?
?2?
{
?3?????private
?AnotherBean?beanOne;
?4?????private
?YetAnotherBean?beanTwo;
?5?????private?int
?i;
?6?????public
?ExampleBean(AnotherBean?anotherBean,?YetAnotherBean?yetAnotherBean,
???????????????????????????????????????????????????????????????????
int
?i)?
?7?
{
?8?????????this.beanOne?=
?anotherBean;
?9?????????this.beanTwo?=
?yetAnotherBean;
10?????????this.i?=
?i;
11?
????}
12?
}
13?
當構造方法中帶多個不同的基本數據類型的參數時,為了避免產生二義性,可以采用type或者index來指定構造方法的參數的類型和順序。
如:
?? type方法
1?<constructor-arg?type="int">
2?<value>7500000</value>
3?</constructor-arg>
4???<constructor-arg?type="java.lang.String">
5?<value>42</value>
6?</constructor-arg>
7?
??? index方法
1?<bean?id="exampleBean"?class="examples.ExampleBean">
2???<constructor-arg?index="0">
3?<value>7500000</value>
4?</constructor-arg>
5???<constructor-arg?index="1">
6?<value>42</value>
7?</constructor-arg>
8?</bean>
9?
總結:
???? type1在靈活性、易用性上不如其他兩種注入模式,
Type2
和Type3型的依賴注入實現則是目前主流的IOC實現模式,
Type3
和Type2模式各有千秋,而Spring都對Type3和Type2類型的依賴注入機制提供了良好支持。
以Type3類型為主,輔之以Type2類型機制作為補充,可以達到最好的依賴注入效果,不過對于基于Spring Framework開發的應用而言,Type2使用更加廣泛。
?
鳳凰涅槃/浴火重生/馬不停蹄/只爭朝夕
???? 隱姓埋名/低調華麗/簡單生活/完美人生