Spring4.0学习笔记 第二章 自动装配(下)

来源:互联网 发布:plc编程入门快捷输入 编辑:程序博客网 时间:2024/05/22 17:26

处理自动装配的歧义性

   

自动装配能够提供很大的帮助,因为它会减少装配应用程序组件时所需要的显式配置的数量。不过,仅有一个bean匹配所需的结果时,自动装配才是有效的。如果不仅有一个bean能够匹配结果的话,这种歧义性会阻碍Spring自动装配属性、构造器参数或方法参数。Spring使用 自动装配(@Autowired  )注入 bean,spring不懂该去选哪个就会报错。 如下例子:

目录结构


DiskInterface为接口,DiskImpl和DiskImpl1为它的实现

DiskImpl:

package interfaces;import org.springframework.stereotype.Component;@Componentpublic class DiskImpl implements DiskInterface {public void play() {System.out.println(" i am ds");}}

DiskImpl1:

package interfaces;import org.springframework.stereotype.Component;@Componentpublic class DiskImpl1 implements DiskInterface {public void play() {System.out.println(" i am ds1");}}
CDConfig:

package config;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;@Configuration//默认扫描config配置类下的bean,如果不指定包名,interfaces包下就没有bean生成@ComponentScan(basePackages={"config","interfaces"})public class CDConfig {}

ConstuctBean:

package interfaces;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;@Componentpublic class ConstuctBean {  @Autowired  private DiskInterface di;  public ConstuctBean(DiskInterface di){  this.di=di;    }  //使用自动注入需要默认的无参构造器 否则spring会报错  public ConstuctBean(){    }  public void show(){  di.play();  }    }


CDplayer测试:

package interfaces;import org.springframework.context.annotation.AnnotationConfigApplicationContext;import config.CDConfig;public class CDPlayer {public static void main(String[] args) {//JavaConfig上下文,加载配置文件AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(CDConfig.class);ConstuctBean cb = (ConstuctBean) ac.getBean("constuctBean");cb.show();}}
报错:[interfaces.DiskInterface] is defined: expected single matching bean but found 2: diskImpl,diskImpl1, 说是期待一个匹配的bean却出现了两个,劳资

不懂怎么选了,spring直接报错罢工。

解决方法:

1、标示首选的bean ,

Spring将会使用首选的bean,而不是其他可选的bean。实际上,你所声明就是“最喜欢”的bean。假设冰激凌就是你最喜欢的甜点。在Spring中,可以通过@Primary来表达最喜欢的方案。@Primary能够与@Component组合用在组件扫描的bean上,也可以与@Bean组合用在Java配置的bean声明中

上面的例子在DiskImpl或者DiskImpl1 的@Component上加入@Primary注解就不会报错了,当出现多个实现bean的时候就自动选择有primary注解的bean

2、在自动注入(@Autowired)的地方加入 @Qualifier("diskImpl"),即@Autowired @Qualifier("diskImpl") 两个注解一起使用,通过

名字指定具体的bean,这样就不会报错了,在这里我们的DiskImpl没有设定特定的bean名,所以默认bean Id为diskImpl。 如果想给DiskImpl指定特定名称也行@Component("dsk")(或者是@Component @Qualifier("dsk")这种方式设定名称比较麻烦,前面那种比较简便),那么在ConstuctBean中就@Autowired @Qualifier("dsk") 可以去到具体的注入的bean实例了。  @Autowired @Qualifier("dsk") 其实等价于@Resource("dsk")推荐使用这种,这种不是spring框架的 是java框架的没有跟spring耦合,@Resource默认是按照bean名字是找到指定的bean对象,如果找不到则按照类型查找(即按照autowired方式)



0 0
原创粉丝点击