當一個接口有多個不同實現類時,使用注解@Autowired時會報
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [xxxx] is defined: expected single matching bean but found 2:xxx1,xxx2異常信息,意思是
Spring 發現兩個類型相同的bean,無法根據類型選擇裝配哪一個。這時候就可以使用@Primary注解設置默認bean,使得項目啟動時只裝配其中一種bean。
@Primary:在眾多相同的Bean中,優先使用@Primary注解的Bean。
方案1-@Qualifier
@Qualifier注解用於細粒度地根據bean名稱選擇bean候選者,是遇到多個相同類型bean時比較常用的解決方案。注解@Autowired 默認是根據類型來自動注入bean,結合 @Qualifier使用時,自動注入的策略就從 byType 轉變成 byName 了。
方案2-@Primary
@Primary可以理解為,裝配bean的時候優先選擇使用@Primary注解的Bean。相同類型的bean不可以同時設置多個@Primary注解。內部實質是設置BeanDefinition的primary屬性。
@Primary案例分析
以在某個相同類型的bean上添加注解@Primary為案例進行分析。測試用例中,Shape接口類有三個實現類。
/**
* 定義bean接口
*/
public interface Shape {
void draw();
}
=========== 我是分割線 =============
@Primary
@Service
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
=========== 我是分割線 =============
@Service
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
=========== 我是分割線 =============
@Service
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
因為實現類 Rectangle 被注解@Primary修飾,所以它將優先被裝配到接口類 Shape。有了上面的代碼之后,我們控制層編寫如下測試用例:
// 優先裝配名字為rectangle的bean
@Autowired
private Shape shape;
@GetMapping("/drawByPrimary")
public String drawByPrimary() {
shape.draw();
return "成功";
}
結束語
以上就是這篇文章的全部內容了,希望本文對大家的學習或者工作能帶來一定的幫助,如有疑問請留言交流。Wiener在此祝各位生活愉快!工作順利!