SpringBoot解决循环调用问题

 更新时间:2024年10月29日 11:26:38   作者:Long-龙哥  
作者在将SpringBoot从1.5版本升级至2.6版本,并迁移至阿里云上运行后,遇到了循环调用问题,在Jetty容器中运行没问题,但在Tomcat容器中就出现了循环引用问题,原因是SpringBoot 2.6不鼓励循环引用,暴露出该问题,作者提供了两种解决思路

SpringBoot解决循环调用

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

背景

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

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 --- [           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.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)

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

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

1.main方法进行debug模式。调节logbcak日志级别为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>

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java线程池中的各个参数如何合理设置

    Java线程池中的各个参数如何合理设置

    这篇文章主要介绍了Java线程池中的各个参数如何合理设置操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • SpringBoot如何优雅的输出异常信息

    SpringBoot如何优雅的输出异常信息

    在Java中,异常(Exception)是Java程序在运行过程中出现的一种特殊情况,会中断正常的程序流程,异常可以是运行时错误,也可以是编程错误,本文将给大家详细的介绍一下SpringBoot如何优雅的输出异常信息,需要的朋友可以参考下
    2023-09-09
  • Socket编程简单示例(聊天服务器)

    Socket编程简单示例(聊天服务器)

    socket编程是在不同的进程间进行网络通讯的一种协议,下面这篇文章主要给大家介绍了关于Socket编程简单示例的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-02-02
  • java基面试础知识详解

    java基面试础知识详解

    这篇文章主要介绍了java基面试础知识,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-08-08
  • Java中Object类常用的12个方法(小结)

    Java中Object类常用的12个方法(小结)

    Java 中的 Object 方法在面试中是一个非常高频的点,本文主要介绍了Java中Object类常用的12个方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • SpringBoot中Excel处理完全指南分享

    SpringBoot中Excel处理完全指南分享

    这篇文章主要介绍了SpringBoot中Excel处理完全指南,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-04-04
  • SpringBoot左脚进门之Maven管理家具体步骤

    SpringBoot左脚进门之Maven管理家具体步骤

    Maven 是一个项目管理和整合工具,通过对 目录结构和构建生命周期 的标准化, 使开发团队用极少的时间就能够自动完成工程的基础构建配置,本文介绍SpringBoot左脚进门之Maven管理家具体步骤,感兴趣的朋友一起看看吧
    2024-12-12
  • Java 实现倒计时功能(由秒计算天、小时、分钟、秒)

    Java 实现倒计时功能(由秒计算天、小时、分钟、秒)

    最近做项目遇到这样的需求,天、小时、分钟、秒的数值都是隔开的,服务器端只返回一个时间戳长度,怎么实现这样的功能呢?下面小编给大家带来了Java 实现倒计时功能的方案,需要的朋友参考下吧
    2018-01-01
  • Java代码编译和反编译的那些事儿

    Java代码编译和反编译的那些事儿

    这篇文章主要给大家介绍了关于Java代码编译和反编译的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Java具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-05-05
  • Java前后端分离的在线点餐系统实现详解

    Java前后端分离的在线点餐系统实现详解

    这是一个基于SpringBoot+Vue框架开发的在线点餐系统。首先,这是一个前后端分离的项目。具有一个在线点餐系统该有的所有功能,感兴趣的朋友快来看看吧
    2022-01-01

最新评论