




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第springboot多數(shù)據(jù)源使用@Qualifier自動注入無效的解決目錄@Qualifier自動注入無效的解決問題問題的根本原因其中問題出在解決問題的方法@Qualifier的作用和應(yīng)用@Qualifier的作用
@Qualifier自動注入無效的解決
問題
使用springboot進(jìn)行多數(shù)據(jù)源時,發(fā)生了單例DataSource對應(yīng)多個DataSourceBean的問題。
具體錯誤如下:XXXXXrequiredasinglebean,but3werefound。通過@Qualifier來區(qū)分,或是在@Bean中添加name屬性來區(qū)分,都沒有作用。
問題的根本原因
主要在于SpringBoot的DataSourceInitializer,該類在autoConfigure包中,用來自動初始化一個內(nèi)置的DataSource實例,在創(chuàng)建該實例的時候發(fā)生了注入的問題。
創(chuàng)建實例的流程(記錄一下方便以后再次調(diào)試):
1.調(diào)用DataSourceInitializer的構(gòu)造方法
2.調(diào)用AbstractAutowireCapableBeanFactory的applyMergedBeanDefinitionPostProcessors方法
3.調(diào)用AbstractAutowireCapableBeanFactory的initializeBean方法
4.AbstractAutowireCapableBeanFactory的applyBeanPostProcessorsBeforeInitialization方法,其中有一個循環(huán)是用多種Bean處理器來處理DataSourceInitializer對象
5.之后使用反射的方式跳轉(zhuǎn)到DataSourceInitializer的init方法
6.里面通過this.applicationContext.getBean(DataSource.class)來獲取所有DataSource的實現(xiàn)類對象實例。
7.DefaultListableBeanFactory的resolveNamedBean方法中來選取實例對象,通過里面的getBeanNamesForType方法獲取到所有的符合requireType(也就是DataSource.class)的對象。
8.如果對象實例的實例數(shù)量大于1,則會進(jìn)入以下的兩個判斷:
判斷是否有Primary的實例,或者是優(yōu)先級高的實例對象,如果有,則將候選對象名賦值給candidateName。沒有則置為空,最后拋出多個實例的異常。
其中問題出在
因為項目中只使用了@Qualifier,而且springboot的DataSourceInitializer沒有對@Qualifier的處理,所以沒有對實例進(jìn)行匹配。
造成多個數(shù)據(jù)源實例。對于存在多數(shù)據(jù)源的情況,他們做的補(bǔ)救措施是在代碼中添加了是否是Primary和是否是HighestPriority的判斷,
來處理采用哪個數(shù)據(jù)源。所以解決的方式也因此出來了。就是將某個實例標(biāo)記為Primary或者HighestPriority。
解決問題的方法
在某個@Bean上添加@Primary注解,就可以做到唯一區(qū)分。
這里其實應(yīng)該還可以通過優(yōu)先級來區(qū)分,但使用@Order發(fā)現(xiàn)并不是這個優(yōu)先級,也沒找到相關(guān)的資料,所以之后再研究一下。
@Qualifier的作用和應(yīng)用
@Qualifier的作用
這是官方的介紹
Thisannotationmaybeusedonafieldorparameterasaqualifierforcandidatebeanswhenautowiring.Itmayalsobeusedtoannotateothercustomannotationsthatcantheninturnbeusedasqualifiers.
簡單的理解就是:
在使用@Autowire自動注入的時候,加上@Qualifier(“test”)可以指定注入哪個對象;
可以作為篩選的限定符,我們在做自定義注解時可以在其定義上增加@Qualifier,用來篩選需要的對象。這個理解看下面的代碼吧,不好解釋。
功能介紹
首先是對(1)的理解。
//我們定義了兩個TestClass對象,分別是testClass1和testClass2
//我們?nèi)绻诹硗庖粋€對象中直接使用@Autowire去注入的話,spring肯定不知道使用哪個對象
//會排除異常requiredasinglebean,but2werefound
@Configuration
publicclassTestConfiguration{
@Bean("testClass1")
TestClasstestClass1(){
returnnewTestClass("TestClass1");
@Bean("testClass2")
TestClasstestClass2(){
returnnewTestClass("TestClass2");
}
下面是正常的引用
@RestController
publicclassTestController{
//此時這兩個注解的連用就類似@Resource(name="testClass1")
@Autowired
@Qualifier("testClass1")
privateTestClasstestClass;
@GetMapping("/test")
publicObjecttest(){
returntestClassList;
@Autowired和@Qualifier這兩個注解的連用在這個位置就類似@Resource(name=“testClass1”)
對(2)的理解
@Configuration
publicclassTestConfiguration{
//我們調(diào)整下在testClass1上增加@Qualifier注解
@Qualifier
@Bean("testClass1")
TestClasstestClass1(){
returnnewTestClass("TestClass1");
@Bean("testClass2")
TestClasstestClass2(){
returnnewTestClass("TestClass2");
@RestController
publicclassTestController{
//我們這里使用一個list去接收testClass的對象
@Autowired
ListTestClasstestClassList=Collections.emptyList();
@GetMapping("/test")
publicObjecttest(){
returntestClassList;
}
我們調(diào)用得到的結(jié)果是
[
{
"name":"TestClass1"
},
{
"name":"TestClass2"
}
]
我們可以看到所有的testclass都獲取到了。接下來我們修改下代碼
@RestController
publicclassTestController{
@Qualifier//我們在這增加注解
@Autowired
ListTestClasstestClassList=Collections.emptyList();
@GetMapping("/test")
publicObjecttest(){
returntestClassList;
}
和上面代碼對比就是在接收參數(shù)上增加了@Qualifier注解,這樣看是有什么區(qū)別,我們調(diào)用下,結(jié)果如下:
[
{
"name":"TestClass1"
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 設(shè)備安全管理培訓(xùn)體系構(gòu)建
- 暖氣跑水協(xié)議書
- 勞動合同簽訂原則
- 執(zhí)行總經(jīng)理聘用合同書
- 物流售后協(xié)議書
- 道路工程清包工合同協(xié)議
- 配送業(yè)務(wù)承包合同協(xié)議
- 水樣比對協(xié)議書
- 旱地承包協(xié)議書
- 車輛保養(yǎng)服務(wù)合同協(xié)議
- 新能源項目糾紛法律適用與案例解析-筆記
- 架子工入場三級安全教育考核試卷
- 安全生產(chǎn)合規(guī)性審核
- 鼓樂鏗鏘 課件-2024-2025學(xué)年高中音樂人音版(2019)必修 音樂鑒賞
- 腎衰竭病歷范文
- 鈑金廠規(guī)劃方案
- 骨質(zhì)疏松用藥治療
- 《LED基礎(chǔ)知識培訓(xùn)》課件
- 世界職業(yè)院校技能大賽中職組“智慧物流作業(yè)組”賽項考試題及答案
- 《汽車燈具的標(biāo)準(zhǔn)》課件
- 一例糖尿病酮中毒個案護(hù)理
評論
0/150
提交評論