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>

总结

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

相关文章

  • 解决idea2020.1找不到程序包和符号的问题

    解决idea2020.1找不到程序包和符号的问题

    这篇文章主要介绍了解决idea2020.1找不到程序包和符号的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • 在Java中读取CSV文件的方式

    在Java中读取CSV文件的方式

    在项目开发中我们经常需要读取csv的内容的操作,读取的逻辑并不复杂,下面这篇文章主要给大家介绍了关于在Java中读取CSV文件的方式,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-06-06
  • 一问详解SpringBoot配置文件优先级

    一问详解SpringBoot配置文件优先级

    在SpringBoot项目当中,我们要想配置一个属性,可以通过这三种方式当中的任意一种来配置都可以,那么优先级怎么算,本文主要介绍了一问详解SpringBoot配置文件优先级,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • Java中String类的一些常见方法总结

    Java中String类的一些常见方法总结

    这篇文章主要给大家介绍了关于Java中String类的一些常见方法,文中包括了Java中String类的基本概念、构造方式、常用方法以及StringBuilder和StringBuffer的使用,涵盖了字符串操作的各个方面,包括查找、转换、比较、替换、拆分、截取等,需要的朋友可以参考下
    2024-11-11
  • Java获取电脑真实IP地址的示例代码

    Java获取电脑真实IP地址的示例代码

    这篇文章主要介绍了Java如何获取电脑真实IP地址,忽略虚拟机等IP地址的干扰,帮助大家更好的理解和使用Java,感兴趣的朋友可以了解下
    2020-09-09
  • Spring Data Jpa+SpringMVC+Jquery.pagination.js实现分页示例

    Spring Data Jpa+SpringMVC+Jquery.pagination.js实现分页示例

    本文介绍了Spring Data Jpa+SpringMVC+Jquery.pagination.js实现分页示例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • String中intern方法的使用场景详解

    String中intern方法的使用场景详解

    这篇文章主要给大家介绍了关于String中intern方法的使用场景,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • java获取系统路径字体、得到某个目录下的所有文件名、获取当前路径

    java获取系统路径字体、得到某个目录下的所有文件名、获取当前路径

    这篇文章主要介绍了java获取系统路径字体、得到某个目录下的所有文件名、获取当前路径,需要的朋友可以参考下
    2014-04-04
  • 解决IDEA中Maven项目中JSTL标签无效问题

    解决IDEA中Maven项目中JSTL标签无效问题

    这篇文章主要介绍了关于IDEA中Maven项目中JSTL标签无效问题的解决方法,需要的朋友可以参考下
    2018-09-09
  • 详解Java Selenium中的键盘控制操作

    详解Java Selenium中的键盘控制操作

    这篇文章主要为大家介绍了如何使用java代码利用Selenium 控制浏览器中需要用到的键盘操作。文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2023-01-01

最新评论