开发者

SpringBoot解决循环调用问题

目录
  • SpringBoot解决循环调用
    • 背景
    • 第一种解决思路
    • 第二种解决思路
  • 总结

    SpringBoot解决循环调用

    此文仅记录自身遇到的问题进行解决处理思路。

    背景

    项目为springboot-1.5的版本,迁移上阿里云,提升springboot版本为2.6.当初最开始的时候用的是jetty容器在本地进行启动,但是最后需要将工程迁移到ali cloud,并且运用K8S作为容器,所以最后将项目打包方式改为jarphp包。

    Jetty 运行的时候是没有丝毫的问题,但是用自带的tomcat 的时候问题就暴漏出来了。

    原因应该是循环引用对于springboot2.6来说是不被鼓励的,所以会直接暴漏出来,最直接简单粗暴的方法:

    第一种解决思路

    下面为允许循环调用的配置操作:

    spring.main.allow-circular-references=true

    第二种解决思路

    因为用最简单的方式进行循环调用,表象一是自己故意做出来的,表象2为当时遇到的。故将两种表象都进行记录,

    所谓循环调用无非就是A调用B,B调用A,导致的springboot 在进行对象加载的时候的一种冲突。下面具体介绍解决思路。

    表象1:

    此为最简单,也是最容易发现的一种循环调用表现:

    2022-10-02 08:44:55.456  WARN 17112 --- [ &nbshttp://www.devze.comp;         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:

    此种直接导致tomcat启动失败,并且在关闭tomcat的时候直接失败,且出现了内存泄漏的问题,错误是一样的,顺手从网上粘贴了一个

     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.c编程客栈oncurrent.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)

    • 表象一直接是在控制台看到的,没啥好说的
    • 表象二这种应用启动的时候直接就提示会造成内存泄漏,但是具体的错误信息是没有的。

    当时解决的时候是分为了一下几步:

    1.main方法进行debug模式。调节logbcak日js志级别为debug,但是效果不是很明显。依然看不到具体的错误信息。

    2.然后自己就只能盲猜了,直接上断点给各种config注解,datasource,很幸运,当加载datasource 的时候报错了。

    • 然后放开断点,没问题出现了表象2的问题,原因是我们使用的druid连接池里面的filter配置,最后注释掉,加载成功了,但是问题依然存在。
    • 那就干脆直接从断点出入手,一路加载debug下去,最后发现了create bean 的时候出现了问题,此时便发现了循环调用的问题。
    • OK,处理掉之后,本地已经可以正常run 起来了。然而,在上到服务器的时候依旧报表象2的错误。

    3. 既然已经知道是循环调用的问题,那么网上搜个logback的配置吧。让它直接打印各个对象的加载和调用log吧

    配它!!

    <logger 编程name="org.springframework.boot">
    	<level value="trace"/>
    	<appender-ref ref="stdout"/>
    </logger>

    总结

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜