spring使用@Async注解導(dǎo)致循環(huán)依賴問題異常的排查記錄
引言
因?yàn)椴伎仡A(yù)警我用到了@async來實(shí)現(xiàn)異步操作,在本地跑的時(shí)候一直沒有報(bào)錯(cuò),可是當(dāng)我打包到服務(wù)器啟動(dòng)的時(shí)候卻報(bào)了一個(gè)BeanCurrentlyInCreationException
Bean with name 'xxx' has been injected into other beans [xxx2] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.
出現(xiàn)循環(huán)依賴報(bào)錯(cuò)了,于是我看了一下代碼,的確有循環(huán)依賴的情況(這個(gè)是不好的習(xí)慣不要學(xué),這里我之前沒注意到,后面可以改一下),但是我記得明明spring是能夠處理使用@Autowired注解形成的循環(huán)的,并不會(huì)導(dǎo)致報(bào)錯(cuò),而且我本地也一直復(fù)現(xiàn)不了,非常的奇怪。
常代碼發(fā)生點(diǎn) spring的doCreateBean方法
于是我寫了一個(gè)spring循環(huán)依賴使用@Async的demo并調(diào)試,異常代碼的發(fā)生點(diǎn)在spring的doCreateBean方法
if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else { //如果代理后的對(duì)象不等于原始對(duì)象就會(huì)拋異常了 }
@Component public class CircularTest { @Autowired CircularTest2 circularTest2; } @Component public class CircularTest2 { @Autowired CircularTest CircularTest; @Async public void async() { } }
開始我的代碼是上面這樣,spring初始化bean的順序是先CircularTest再CircularTest2,每到初始化CircularTest2執(zhí)行異常處代碼的時(shí)候,直接earlySingletonReference返回的是null,所以一直復(fù)現(xiàn)不了,這時(shí)候我突然想到是不是spring初始化順序的原因,因?yàn)橹耙灿龅竭^spring順序不確定的問題,于是我改了一下代碼
修改
@Component public class CircularTest { @Autowired CircularTest2 circularTest2; @Async public void async() { } } @Component public class CircularTest2 { @Autowired CircularTest CircularTest; }
我把@Async方法換了個(gè)位置,這次竟然真的就復(fù)現(xiàn)了該異常,所以看來我本地的和服務(wù)器上的雖然代碼一致,但是最終跑起來的spring的bean加載順序變成不一樣了,因?yàn)閟pring容器載入bean的順序是不確定的,框架本身也沒有約定特定順序的邏輯規(guī)范,不過利用@Ordered,@Dependon等等注解自己實(shí)現(xiàn)依賴順序那是另外一回事了,嗯復(fù)現(xiàn)bug了,下面調(diào)試一下spring循環(huán)依賴使用@Async注解為啥會(huì)報(bào)錯(cuò)
以上就是spring使用@Async注解導(dǎo)致循環(huán)依賴問題異常的排查記錄的詳細(xì)內(nèi)容,更多關(guān)于spring @Async循環(huán)依賴異常的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
springcloud client指定注冊到eureka的ip與端口號(hào)方式
這篇文章主要介紹了springcloud client指定注冊到eureka的ip與端口號(hào)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03Java8 stream 中利用 groupingBy 進(jìn)行多字段分組求和案例
這篇文章主要介紹了Java8 stream 中利用 groupingBy 進(jìn)行多字段分組求和案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-08-08詳解Spring Boot + Mybatis 實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源
這篇文章主要介紹了Spring Boot + Mybatis 實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04java 動(dòng)態(tài)加載的實(shí)現(xiàn)代碼
這篇文章主要介紹了java 動(dòng)態(tài)加載的實(shí)現(xiàn)代碼的相關(guān)資料,Java動(dòng)態(tài)加載類主要是為了不改變主程序代碼,通過修改配置文件就可以操作不同的對(duì)象執(zhí)行不同的功能,需要的朋友可以參考下2017-07-07Java如何利用CompletableFuture描述任務(wù)之間的關(guān)系
Java如何根據(jù)線程的執(zhí)行結(jié)果執(zhí)行下一步動(dòng)作呢,F(xiàn)uture的另一個(gè)實(shí)現(xiàn)類CompletableFuture能夠優(yōu)雅的解決異步化問題,下面就跟隨小編一起了解一下吧2023-07-07