引言 spring實現的bean自動註入在項目開發中是一個經常使用到的功能,但自動裝配兩個或多個bean時,會拋出NoUniqueBeanDefinitionException:No qualifying bean of type 'com' available: expected single m ...
引言
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; } }