Sprint Boot————@Qualifier、@Primary
引言
使用@Autowired自動注入時:
如果注入的接口有多個實現類,如下所示:
那么如果不指定具體是哪個實現類的Bean,在Spring Boot啟動時就會發生異常(下圖請點擊查看):
?異常的描述信息非常簡單,就是告訴開發者,自動注入的地方需要一個Bean,而spring 容器卻找到了3個實現類的Bean。
Action(可以采取的行動): 考慮使用@Primary注解或@Qualifier注解。
?
@Primary
此注解用在類上面,官方解釋如下:
簡單翻譯過來就是,這個注解相當于Spring 的xml配置文件中bean標簽里的 primary屬性。
它表示在需要自動注入一個單值依賴的地方,卻有多個候選依賴,那么這個注解會指定一個類作為preference(偏好)選擇。
可以簡單理解為,我們把@Primary注解標記在任意一個類上面,在使用@Autowired注入的時候,如果不特殊指明(如何特殊指明請看@Qualifier的講解),那么默認就注入被@Primary標記的類。
但是只可以指定一個類作為偏好類,否則依然會產生沖突。
@Qualifier
此注解用在屬性上、方法上、參數上等,官方解釋如下:
翻譯過來就是說,這個注解用在屬性上,或參數上,在自動注入的時候作為多個候選bean的限定。也可以使用在其他的隨后會被用于限定bean的定制注解上。
其實大多數用于屬性上和@Autowired一起聯用。
這個注解有一個參數:
(default關鍵字應該是java8中引入的關鍵字,不過我也是第一次見過這種寫法,可能是孤陋寡聞,各位大神輕噴)
稍微思考一下就可以猜到,如果不為@Qualifier注解指定參數那么默認使用類的默認別名,即類的首字母小寫,比如:
ChineseTeacher類的默認別名是:chineseTeacher;
EnglishTeacher類的默認別名是:englishTeacher;
MathTeacher類的默認別名是:mathTeacher。
?使用默認別名的方法很簡單,直接用類的默認別名來命名我們的自動注入對象,如下所示:
Teacher接口有三個實現類:ChineseTeacher、EnglishTeacher、MathTeacher,我們不需要使用@Primary,也不使用@Qualifier,直接在自動注入的變量上使用默認別名,依然可以注入成功。
是的,當我們在自動注入的時候使用類的默認別名,就不會發生候選Bean沖突的問題。
使用@Qualifier或@Primary注解僅僅是在你不想用默認別名來命名注入的bean或是忘記了使用默認別名的情形。
當我們不使用默認別名來使用自動注入功能,我們就需要使用@Qualifier來指定選擇的類型,像下面這樣:
注意,如果想將ChineseTeacher注入到teacher對象中,就必須給ChineseTeacher類設置別名。
@Service、@Component等注解都可以傳入一個字符串作為類的別名。
注意:使用@Qualifier注入bean的時候,它所選取的類的別名需要與具體的類的別名一致,否則會報無法找到指定類型的錯誤。
?總結
羅里吧嗦說了這么多,其實總結起來很簡單。
我們自動注入的時候,如果有多個候選實現類的bean,spring boot啟動的時候就不知道該選擇哪個bean進行注入,因此會報錯。
使用@Primary可以指定一個首選Bean注入;使用@Qualifier可以在自動注入的地方通過傳入一個限定名(也就是類的別名)來選取指定的實現類,只不過必須與類的別名一致(如果不傳限定名,就使用類的默認別名)
如果既不用@Primary也不用@Qualifier,那就必須在自動注入的時候直接以類的默認別名來命名。
給(spring ioc容器管理的)類設置別名的方式是:@Service("別名")、@Component("別名") 、@Bean("別名") 等等。
?
總結
以上是生活随笔為你收集整理的Sprint Boot————@Qualifier、@Primary的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java语言执行模式,使用java.ex
- 下一篇: c++保留小数点后三位数_C++保留有效