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

处理自动装配的歧义性

   

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

目录结构


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

DiskImpl:

package interfaces;

import org.springframework.stereotype.Component;

@Component
public class DiskImpl implements DiskInterface {
	public void play() {
		System.out.println(" i am ds");
	}

}

DiskImpl1:

package interfaces;

import org.springframework.stereotype.Component;

@Component
public 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;

@Component
public 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值