spring使用@Async注解導(dǎo)致循環(huán)依賴問題異常的排查記錄
引言
因為布控預(yù)警我用到了@async來實現(xiàn)異步操作,在本地跑的時候一直沒有報錯,可是當我打包到服務(wù)器啟動的時候卻報了一個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)依賴報錯了,于是我看了一下代碼,的確有循環(huán)依賴的情況(這個是不好的習(xí)慣不要學(xué),這里我之前沒注意到,后面可以改一下),但是我記得明明spring是能夠處理使用@Autowired注解形成的循環(huán)的,并不會導(dǎo)致報錯,而且我本地也一直復(fù)現(xiàn)不了,非常的奇怪。
常代碼發(fā)生點 spring的doCreateBean方法
于是我寫了一個spring循環(huán)依賴使用@Async的demo并調(diào)試,異常代碼的發(fā)生點在spring的doCreateBean方法
if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else { //如果代理后的對象不等于原始對象就會拋異常了 }
@Component public class CircularTest { @Autowired CircularTest2 circularTest2; } @Component public class CircularTest2 { @Autowired CircularTest CircularTest; @Async public void async() { } }
開始我的代碼是上面這樣,spring初始化bean的順序是先CircularTest再CircularTest2,每到初始化CircularTest2執(zhí)行異常處代碼的時候,直接earlySingletonReference返回的是null,所以一直復(fù)現(xiàn)不了,這時候我突然想到是不是spring初始化順序的原因,因為之前也遇到過spring順序不確定的問題,于是我改了一下代碼
修改
@Component public class CircularTest { @Autowired CircularTest2 circularTest2; @Async public void async() { } } @Component public class CircularTest2 { @Autowired CircularTest CircularTest; }
我把@Async方法換了個位置,這次竟然真的就復(fù)現(xiàn)了該異常,所以看來我本地的和服務(wù)器上的雖然代碼一致,但是最終跑起來的spring的bean加載順序變成不一樣了,因為spring容器載入bean的順序是不確定的,框架本身也沒有約定特定順序的邏輯規(guī)范,不過利用@Ordered,@Dependon等等注解自己實現(xiàn)依賴順序那是另外一回事了,嗯復(fù)現(xiàn)bug了,下面調(diào)試一下spring循環(huán)依賴使用@Async注解為啥會報錯
以上就是spring使用@Async注解導(dǎo)致循環(huán)依賴問題異常的排查記錄的詳細內(nèi)容,更多關(guān)于spring @Async循環(huán)依賴異常的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
springcloud client指定注冊到eureka的ip與端口號方式
這篇文章主要介紹了springcloud client指定注冊到eureka的ip與端口號方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03Java8 stream 中利用 groupingBy 進行多字段分組求和案例
這篇文章主要介紹了Java8 stream 中利用 groupingBy 進行多字段分組求和案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08詳解Spring Boot + Mybatis 實現(xiàn)動態(tài)數(shù)據(jù)源
這篇文章主要介紹了Spring Boot + Mybatis 實現(xiàn)動態(tài)數(shù)據(jù)源,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04Java如何利用CompletableFuture描述任務(wù)之間的關(guān)系
Java如何根據(jù)線程的執(zhí)行結(jié)果執(zhí)行下一步動作呢,F(xiàn)uture的另一個實現(xiàn)類CompletableFuture能夠優(yōu)雅的解決異步化問題,下面就跟隨小編一起了解一下吧2023-07-07