SpringBoot解決循環(huán)調(diào)用問(wèn)題
SpringBoot解決循環(huán)調(diào)用
此文僅記錄自身遇到的問(wèn)題進(jìn)行解決處理思路。
背景
項(xiàng)目為springboot-1.5的版本,遷移上阿里云,提升springboot版本為2.6.當(dāng)初最開(kāi)始的時(shí)候用的是jetty容器在本地進(jìn)行啟動(dòng),但是最后需要將工程遷移到ali cloud,并且運(yùn)用K8S作為容器,所以最后將項(xiàng)目打包方式改為jar包。
Jetty 運(yùn)行的時(shí)候是沒(méi)有絲毫的問(wèn)題,但是用自帶的tomcat 的時(shí)候問(wèn)題就暴漏出來(lái)了。
原因應(yīng)該是循環(huán)引用對(duì)于springboot2.6來(lái)說(shuō)是不被鼓勵(lì)的,所以會(huì)直接暴漏出來(lái),最直接簡(jiǎn)單粗暴的方法:
第一種解決思路
下面為允許循環(huán)調(diào)用的配置操作:
spring.main.allow-circular-references=true
第二種解決思路
因?yàn)橛米詈?jiǎn)單的方式進(jìn)行循環(huán)調(diào)用,表象一是自己故意做出來(lái)的,表象2為當(dāng)時(shí)遇到的。故將兩種表象都進(jìn)行記錄,
所謂循環(huán)調(diào)用無(wú)非就是A調(diào)用B,B調(diào)用A,導(dǎo)致的springboot 在進(jìn)行對(duì)象加載的時(shí)候的一種沖突。下面具體介紹解決思路。
表象1:
此為最簡(jiǎn)單,也是最容易發(fā)現(xiàn)的一種循環(huán)調(diào)用表現(xiàn):
2022-10-02 08:44:55.456 WARN 17112 --- [ main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'a': Unsatisfied dependency expressed through field 'b'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'b': Unsatisfied dependency expressed through field 'a'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'a': Requested bean is currently in creation: Is there an unresolvable circular reference?
2022-10-02 08:44:55.456 INFO 17112 --- [ main] ConditionEvaluationReportLoggingListener :Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-10-02 08:44:55.472 ERROR 17112 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :***************************
APPLICATION FAILED TO START
***************************Description:
The dependencies of some of the beans in the application context form a cycle:
┌─────┐
| a (field private com.example.service.B com.example.service.A.b)
↑ ↓
| b (field private com.example.service.A com.example.service.B.a)
└─────┘
表象2:
此種直接導(dǎo)致tomcat啟動(dòng)失敗,并且在關(guān)閉tomcat的時(shí)候直接失敗,且出現(xiàn)了內(nèi)存泄漏的問(wèn)題,錯(cuò)誤是一樣的,順手從網(wǎng)上粘貼了一個(gè)
07-Sep-2020 19:09:11.196 WARNING [localhost-startStop-1] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [system] appears to have started a thread named [pool-1-thread-4] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
java.lang.Thread.run(Thread.java:748)
- 表象一直接是在控制臺(tái)看到的,沒(méi)啥好說(shuō)的
- 表象二這種應(yīng)用啟動(dòng)的時(shí)候直接就提示會(huì)造成內(nèi)存泄漏,但是具體的錯(cuò)誤信息是沒(méi)有的。
當(dāng)時(shí)解決的時(shí)候是分為了一下幾步:
1.main方法進(jìn)行debug模式。調(diào)節(jié)logbcak日志級(jí)別為debug,但是效果不是很明顯。依然看不到具體的錯(cuò)誤信息。
2.然后自己就只能盲猜了,直接上斷點(diǎn)給各種config注解,datasource,很幸運(yùn),當(dāng)加載datasource 的時(shí)候報(bào)錯(cuò)了。
- 然后放開(kāi)斷點(diǎn),沒(méi)問(wèn)題出現(xiàn)了表象2的問(wèn)題,原因是我們使用的druid連接池里面的filter配置,最后注釋掉,加載成功了,但是問(wèn)題依然存在。
- 那就干脆直接從斷點(diǎn)出入手,一路加載debug下去,最后發(fā)現(xiàn)了create bean 的時(shí)候出現(xiàn)了問(wèn)題,此時(shí)便發(fā)現(xiàn)了循環(huán)調(diào)用的問(wèn)題。
- OK,處理掉之后,本地已經(jīng)可以正常run 起來(lái)了。然而,在上到服務(wù)器的時(shí)候依舊報(bào)表象2的錯(cuò)誤。
3. 既然已經(jīng)知道是循環(huán)調(diào)用的問(wèn)題,那么網(wǎng)上搜個(gè)logback的配置吧。讓它直接打印各個(gè)對(duì)象的加載和調(diào)用log吧
配它!!
<logger name="org.springframework.boot"> <level value="trace"/> <appender-ref ref="stdout"/> </logger>
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- 如何解決SpringBoot2.6及之后版本取消了循環(huán)依賴(lài)的支持問(wèn)題
- SpringBoot構(gòu)造器注入循環(huán)依賴(lài)及解決方案
- SpringBoot中@Autowired注入service時(shí)出現(xiàn)循環(huán)依賴(lài)問(wèn)題的解決方法
- SpringBoot3.x循環(huán)依賴(lài)問(wèn)題解決方案
- springboot配置允許循環(huán)依賴(lài)問(wèn)題
- SpringBoot啟動(dòng)報(bào)錯(cuò)屬性循環(huán)依賴(lài)報(bào)錯(cuò)問(wèn)題的解決
相關(guān)文章
Java線(xiàn)程池中的各個(gè)參數(shù)如何合理設(shè)置
這篇文章主要介紹了Java線(xiàn)程池中的各個(gè)參數(shù)如何合理設(shè)置操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06Java中Object類(lèi)常用的12個(gè)方法(小結(jié))
Java 中的 Object 方法在面試中是一個(gè)非常高頻的點(diǎn),本文主要介紹了Java中Object類(lèi)常用的12個(gè)方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12SpringBoot左腳進(jìn)門(mén)之Maven管理家具體步驟
Maven 是一個(gè)項(xiàng)目管理和整合工具,通過(guò)對(duì) 目錄結(jié)構(gòu)和構(gòu)建生命周期 的標(biāo)準(zhǔn)化, 使開(kāi)發(fā)團(tuán)隊(duì)用極少的時(shí)間就能夠自動(dòng)完成工程的基礎(chǔ)構(gòu)建配置,本文介紹SpringBoot左腳進(jìn)門(mén)之Maven管理家具體步驟,感興趣的朋友一起看看吧2024-12-12Java 實(shí)現(xiàn)倒計(jì)時(shí)功能(由秒計(jì)算天、小時(shí)、分鐘、秒)
最近做項(xiàng)目遇到這樣的需求,天、小時(shí)、分鐘、秒的數(shù)值都是隔開(kāi)的,服務(wù)器端只返回一個(gè)時(shí)間戳長(zhǎng)度,怎么實(shí)現(xiàn)這樣的功能呢?下面小編給大家?guī)?lái)了Java 實(shí)現(xiàn)倒計(jì)時(shí)功能的方案,需要的朋友參考下吧2018-01-01Java前后端分離的在線(xiàn)點(diǎn)餐系統(tǒng)實(shí)現(xiàn)詳解
這是一個(gè)基于SpringBoot+Vue框架開(kāi)發(fā)的在線(xiàn)點(diǎn)餐系統(tǒng)。首先,這是一個(gè)前后端分離的項(xiàng)目。具有一個(gè)在線(xiàn)點(diǎn)餐系統(tǒng)該有的所有功能,感興趣的朋友快來(lái)看看吧2022-01-01