Spring IoC
public   class  Foo  {①
  
private  String name;
  
private   int  age;
  
public  String toString() {
     
return   " The Foo's Name is :  "   +   this .name  +   "  The Foo's Age is :  "   +   this .age;
  }

  
public  String getName()  { }
  
public   void  setName(String name)  { }
  
public   int  getAge()  { }
  
public   void  setAge( int  age)  { }
}


public   class  Bar  {②
  
private  String address;
  
public  String toString() {
     
return   " The Bar's Address is :  "   +   this .address;
  }

  
public  String getAddress()  { }
  
public   void  setAddress(String address)  { }
}


public   class  Base  {③
  
private  Foo foo;
  
private  Bar bar;
  
public  String toString() {
     
return   " Base : [ "   +   this .foo.toString()  + "   " +   this .bar.toString() +   " ] " ;
  }

  
public  Foo getFoo()  { }
  
public   void  setFoo(Foo foo)  { }
  
public  Bar getBar()  { }
  
public   void  setBar(Bar bar)  { }
}



<? xml version="1.0" encoding="UTF-8" ?>
< beans  xmlns =" " >
  
< bean  id ="foo"  class ="com.tony.test.Foo" >
     
< property  name ="name"  value ="Tony" />
     
< property  name ="age"  value ="27" />
  
</ bean  >
  
< bean  id ="bar"  class ="com.tony.test.Bar" >
     
< property  name ="address"  value ="China Tianjin" />
  
</ bean >
  
< bean  id ="base"  class ="com.tony.test.Base" >
     
< property  name ="foo" >
        
< ref  local ="foo" />
     
</ property >
     
< property  name ="bar" >
        
< ref  local ="bar" />
     
</ property >
  
</ bean >
</ beans >

import  org.springframework.context.ApplicationContext;
import  org.springframework.context.support.ClassPathXmlApplicationContext;
public   class  MainClass  {④
  
public   static   void  main(String[] args)  {    
        String[] locations 
=   { " spring-config-beans.xml " } ;    
        ApplicationContext ctx 
=   new  ClassPathXmlApplicationContext(locations);    
        Base main 
=  (Base) ctx.getBean( " base " );⑤   
        System.out.println(main);⑥   
   }

}


我们来看看上面代码的含义,首先在代码①和②处我们分别定义了两个名为Foo和Bar的Bean,在③处我们通过set方法将两个Bean注入进Base类中,并且在Base类中定义了toString方法来打印出Foo和Bar的信息,在④处我们定义了一个MainClass来执行我们的代码,在⑤处我们通过getBean获得配置文件中配置的id为base的Bean并在⑥出将其信息打印至控制台,控制台输出信息如下:
Base : [The Foo's Name is : Tony The Foo's Age is : 27 The Bar's Address is : China Tianjin]
看到上面习以为常的配置信息和set get方法我们根本不会有任何想法,可是当我们看到了Spring2.5注释特性的时候我们发现自己真的错了,程序竟然还可以写成这么简单。

三、使用 @Autowired 注释
import  org.springframework.beans.factory.annotation.Autowired;
public   class  Base  {
  @Autowired① 使用了一个名为Autowired的注释
  
private  Foo foo;
  @Autowired②
  
private  Bar bar;
  
public  String toString() {
     
return   " Base : [ "   +   this .foo.toString()  + "   " +   this .bar.toString() +   " ] " ;
  }

}



<!--  该 BeanPostProcessor 将自动对标注 @Autowired 的 Bean 进行注入  --> ③  
  
< bean  class ="org.springframework.beans.factory.annotation.
                              AutowiredAnnotationBeanPostProcessor"
/>
  
  
< bean  id ="foo"  class ="com.tony.test.Foo" >
     
< property  name ="name"  value ="Tony" />
     
< property  name ="age"  value ="27" />
  
</ bean >
  
< bean  id ="bar"  class ="com.tony.test.Bar" >
     
< property  name ="address"  value ="China Tianjin" />
  
</ bean >
  
<!--  此时移除了Base的配置信息  -->  ④
  
< bean  id ="base"  class ="com.tony.test.Base" />

我们在①和②处使用了@Autowired注释,它可以对类的成员变量、方法及构造函数进行标注,完成自动装配的工作,在③处我们为了使@Autowired注释生效必须在Spring容器中声明AutowiredAnnotationBeanPostProcessor Bean它通过扫描 Spring 容器中所有 Bean,当发现 Bean 中拥有 @Autowired 注释时就找到和其相匹配(默认按类型匹配)的 Bean,并将其注入,而此时我们在声明Base的时候(④处)就不用写它的配置信息了,更可以将Base类中的set和get方法删除。@Autowired还可以通过类的构造函数来进行自动装配。

在默认情况下使用 @Autowired 注释进行自动注入时,Spring 容器中匹配的候选 Bean 数目必须有且仅有一个。当找不到一个匹配的 Bean 时,Spring 容器将抛出 BeanCreationException 异常,并指出必须至少拥有一个匹配的 Bean


import  org.springframework.beans.factory.annotation.Autowired;
public   class  Base  {
  
private  Foo foo;
  
private  Bar bar;
  @Autowired
  
public  Base(Foo foo,Bar bar) { ①
     
this .foo  =  foo;
     
this .bar  =  bar;
  }

  
public  String toString() {
     
return   " Base : [ "   +   this .foo.toString()  + "   " +   this .bar.toString() +   " ] " ;
  }

}


我们增加了一个构造函数,通过它来对我们的成员变量进行赋值,我们同时也为这个构造函数添加了@Autowired注释(①处)使其可以自动将Foo和Bar两个成员变量装配进来。


当不能确定 Spring 容器中一定拥有某个类的 Bean 时,可以在需要自动注入该类 Bean 的地方可以使用 @Autowired(required = false),这等于告诉 Spring:在找不到匹配 Bean 时也不报错

四、使用 @Qualifier 注释
有时我们会遇到这样一种情况,我们定义了两个类型相同数据不同的Bean,我们此时需要用到其中一个Bean来供我们使用,使用@Qualifier注释就可以满足我们的要求,当使用@Qualifier注释时自动注入的策略就从 byType 转变成 byName 了。
< bean  id ="bar"  class ="com.tony.test.Bar" >
  
< property  name ="address"  value ="China Tianjin" />
</ bean >
< bean  id ="bar2"  class ="com.tony.test.Bar" >
  
< property  name ="address"  value ="China Beijing" />
</ bean >

import  org.springframework.beans.factory.annotation.Autowired;
import  org.springframework.beans.factory.annotation.Qualifier;
public   class  Base  {
  
private  Bar bar;
  @Autowired ③
  
public  Base(@Qualifier( " bar2 " )Bar bar) { ④
     
this .bar  =  bar;
  }

  
public  String toString() {
     
return   " Base : [ " +   this .bar.toString() +   " ] " ;
  }

}


①和②处我们分别定义了两个类型为Bar的Bean,②处Bar的address为China Beijing并且Bean的名称为bar2,在代码清单4.2的③处我们同样使用了@Autowired注释为Bar的构造函数进行自动装配,可是在④处我们通过@Qualifier("bar2")来明确指定我们需要将id为bar2的Bean装配进来。我们还可以为成员变量使用@Qualifier注释。
import  org.springframework.beans.factory.annotation.Autowired;
import  org.springframework.beans.factory.annotation.Qualifier;
public   class  Base  {
  @Autowired ①
  @Qualifier(
" bar2 " ) ②
  
private  Bar bar;
  
public  String toString() {
     
return   " Base : [ " +   this .bar.toString() +   " ] " ;
  }

}



五、使用 @Component 注释

使用了@Autowired注释后我们发现自动注入真的非常简单,但是我们还是得在配置文件中定义相应的<Bean>,如果我们能在配置文件中完全移除Bean的定义那就更好了,Spring2.5就为我们提供了这一可能。
import  org.springframework.stereotype.Component;
@Component ①
public   class  Bar  {
  
private  String address  =   " China Tianjin " ;
  
public  String toString() {
     
return   " The Bar's Address is :  "   +   this .address;
  }

}


import  org.springframework.stereotype.Component;
@Component(
" base " ) ②
public   class  Base  {
  @Resource
  
private  Bar bar;
  
public  String toString() {
     
return   " Base : [ " +   <spa
分享到:
评论