Spring@Autowired注解与自动装配

来源:互联网 发布:ubuntu etc rc.local 编辑:程序博客网 时间:2024/06/02 02:00

在没有@Autowired注解之前,如果我们想将A Bean实例注入给B Bean的name属性,我们一般是在配置文件中这样写:

<bean id="b" class="">  <property name="name" ref="a"></bean><bean id="a" class=""/>

这种方式需要我们提供相应属性的set()方法,这种方式也正是通过set()方法完成的属性注入。

而@Autowired注解的作用就是自动搜索Spring容器中符合条件的Bean实例,并注入给对应的属性,从而完成自动装配,因此他不需要我们提供相应属性的set方法,这大大减小了我们的代码量。

比如下面这个例子

一:

Chinese拥有Axe类型的一个属性 咱们使用@Autowired完成属性注入的自动装配

1:Chinese.java

@Componentpublic class Chinese implements Person{@Autowiredprivate Axe axe;public Chinese() {System.out.println("Spring实例化主调bean:Chinese实例...");}@Overridepublic void useAxe() {System.out.println(axe.chop());}}

上面我们通过@Component将该类注解为Bean,然后通过@Autowired注解了Axe类型的axe属性,@Autowired注解就告诉Spring容器,去找Axe类型的Bean,如果找到,则将该Bean注入给axe,如果找不到,则不做任何处理,但是如果找到多个Axe类型的Bean,程序则会报错,后面还会介绍。可以看到,程序中我们并没有提供相应的set方法。

2:StoneAxe.java 该类实现Axe接口

@Componentpublic class StoneAxe implements Axe{@Overridepublic String chop() {return "石斧真难用";}}
该类同样使用了@Component注解标注成Bean,而且实现了Axe接口,也就是说该Bean是属于Axe类型的Bean,因此Spring容器自动查找到该Bean后,发现满足条件,就会将该Bean自动注入给Chinese Bean的axe属性。

3:测试方法 BeanTest

public class BeanTest {public static void main(String[]args){AbstractApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");Chinese chinese = (Chinese) ctx.getBean("chinese", Person.class);chinese.useAxe();}}

4:输出结果


Spring实例化主调bean:Chinese实例...
石斧真难用


从输出结果看我们并没有提供set方法,但是使用@Autowires注解让Spring容器完成了自动装配

二:

我们上面有提到,@Autowired自动装配当搜索到一个符合类型条件的Bean时会自动注入,但是如果找到多个Axe类型的Bean,程序则会报错,那么咱们再创建一个SteelAxe Bean且实现Axe接口,这样就同时存在了两个Axe类型的Bean,我们来看一下:

1:SteelAxe.java

@Componentpublic class SteelAxe implements Axe{@Overridepublic String chop() {// TODO Auto-generated method stubreturn "钢斧真好用";}}

这样当使用@Autowired注解Chinese Axe类型axe属性时,Spring会找到SteelAxe、StoneAxe两个Bean

2:输出结果报错

 org.springframework.beans.factory.BeanCreationException


三:



那如果我们需要同一类型的不同Bean,那怎么办?比如我们需要创建Axe类型的不同Bean而不让程序报错,那就是使用@Autowired注解集合,如下,我们通过@Autowired注解一个Axe[]axes数组,这样Spring会寻找所有符合要求类型的的Bean,然后将所有的Bean的实例组成新的集合。如下我们使用@Autowired注解标注一个数组

1:Chinese.java

@Componentpublic class Chinese implements Person{@Autowiredprivate Axe [] axes;public Axe[] getAxes() {return axes;}public void setAxes(Axe[] axes) {this.axes = axes;}@Overridepublic void useAxe() {System.out.println(java.util.Arrays.toString(axes));}}


2:我们创建两个Axe类型的Bean SteelAxe Bean、StoneAxe Bean

3:测试程序 BeanTest.java

public class BeanTest {public static void main(String[]args){AbstractApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");Chinese chinese = (Chinese) ctx.getBean("chinese", Person.class);chinese.useAxe();}}


4:运行结果



[com.mao.test.SteelAxe@7a30d1e6, com.mao.test.StoneAxe@5891e32e]
所以,当我们使用@Autowired修饰集合时,Spring容器会自动搜索所有Axe类型的Bean,并将这些Axe实例作为数组元素创建新的数组,最后将数组注入给axes,因此 这里虽然存在了两个Axe类型的Bean,但是程序并没有报错。

四:



使用@Autowired修饰Set集合和数组是类似的,只不过修饰set集合时需要使用泛型,如下 我们将Chinese.java修改为:

1:Chinese.java

@Componentpublic class Chinese implements Person{//修饰数组@Autowiredprivate Axe [] axes;//修饰set集合@Autowiredprivate Set<Axe>axeset;public Chinese() {System.out.println("Spring实例化主调bean:Chinese实例...");}@Overridepublic void useAxe() {//输出集合元素System.out.println(java.util.Arrays.toString(axes));//创建迭代器遍历set集合元素Iterator it=axeset.iterator();while(it.hasNext()){System.out.println(it.next());}}}


2:我们再看输出结果

Spring实例化主调bean:Chinese实例...
[com.mao.test.SteelAxe@43bd930a, com.mao.test.StoneAxe@33723e30]
com.mao.test.SteelAxe@43bd930a
com.mao.test.StoneAxe@33723e30


因此,使用@Autowired修饰数组还是set集合都可以达到相同的目的

0 0
原创粉丝点击