本文研究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




 

其中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使用更加广泛。  


 

 

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