本文研究Spring的三种依赖注入实现类型——接口注入(Interface Injection)、设值注入(Setter Injection)、构造子注入(Constructor Injection)。
Type1 接口注入: 传统的创建接口对象的方法, 借助接口来将调用者与实现者分离。如下面的代码所示:
在代码中创建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
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
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
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
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
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
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使用更加广泛。
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
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