GirlsBoy
回首向来萧瑟处,归去,也无风雨也无晴。
引言

    spring实现的bean自动注入在项目开发中是一个经常使用到的功能,但自动装配两个或多个bean时,会抛出NoUniqueBeanDefinitionException:No qualifying bean of type 'com' available: expected single matching bean but found 2异常。最常见的现象就是一个接口有两个实现类。spring允许一个类创建两个或多个bean。但如果bean是自动装配的,就会抛出异常。

原因分析

    spring应用程序启动时,应用程序将beans加载到ApplicationContext中,接着添加依赖bean生成其他类型bean,如果两个或多个bean可用于为一个bean注入,则会抛出NoUniqueBeanDefinitionException:No qualifying bean of type 'com' available: expected single matching bean but found异常。

异常演示    

public interface Animal {
  public String noise();
} 
@Component
public class Dog implements Animal{
  @Override
  public String noise() {
    return "bowwow";
  }
}
@Component
public class Bea implements Animal{
  @Override
  public String noise() {
    return "buzz";
  }
}
@Service
public class Zoo {
  @Autowired
  public Animal animal;
}

如此,工程启动便会抛出异常。

解决方案

方案一

    Autowired使用java约定变量名,如dog是Dog的约定变量名,所以,使用注解@Autowired可以将Dog变量名命名为dog,如下

@Service
public class Zoo {

  @Autowired
  public Animal dog;
}

方案二

    如果类的数据类型与加载的bean类型匹配,bean将会自动装载为对应的类型。所以,不用接口或抽象类名定义bean,具体实现如下

@Service
public class Zoo {

  @Autowired
  public Dog animal;
}

方案三

       可以使用注解@Primary,Spring的@Primary注解,是框架在3.0版中引入的。其作用与功能,当有多个相同类型的bean时,使用@Primary来赋予bean更高的优先级。代码如下

@Component
@Primary
public class Dog implements Animal{
  @Override
  public String noise() {
    return "bowwow";
  }
}

方案四

    spring注解@Qualifier用于从多个bean中选择一个bean。@Qualifier 注释将被配置为匹配 bean 名称。@Autowired 注释使用限定符的名称来匹配和加载 bean。 

@Service
public class Zoo {

  @Autowired
  @Qualifier("dog")
  public Animal animal;
}

方案五

    限定符与方法参数一起使用。

@Service
public class Zoo {
    private Animal animal;
    @Autowired
    public vod setAnimal(@Qualifier("dog") Animal animal){
      this.animal = animal;
    }
  }

  

 
posted on 2023-01-05 14:43  GirlsBoy  阅读(810)  评论(0编辑  收藏  举报

java\web应用开发&研究

梦想程序改变生活

成为一个了不起的人