spring循环注入异常问题的解决方案
作者:chengxu2011 发布时间:2021-06-29 02:21:18
今天在做项目的时候突然遇到一个问题:启动服务器的时候spring
没报错,可是当我访问某个页面的时候spring报Request bean is currently in creation: is there an unresolvable circular reference
的错误,后来查了些资源终于找出来了原因,这里和大家分享一下;
首先产生这个错误的原因是因为spring循环注入了,什么是循环注入?举个列子我有一个类A,A有一个构造器里面的参数是类B,然后类B里面有个构造器参数是类C,类C里面有个构造器参数是类A,就是我们会发现其实引用循环了A 里面有B的引用,B里面有C的引用,C里面又有A的引用。
循环依赖又分为构造器循环依赖和set
循环依赖:
首先讲一下构造器的循环依赖:
public class A
{
public A(B b)
{
}
}
public class B
{
public B(C c)
{
}
}
public class C
{
public C(A a)
{
}
}
当我们用spring来加载A的时候spring的流程是这样的:
1:spring创建A首先去当前创建池中去查找当前A是否在创建,如果发明没有创建则准备其构造器需要的参数B,然后把创建A的标识放入当前创建池中。
2:spring创建B首先去当前创建池中去查找当前B是否在创建,如果发现没有创建则准备其构造器需要的参数C,然后把创建B的标识放入当前创建池中。
3:spring创建C首先去当前创建池中去查找当前C是否在创建,如果发现没有创建则准备其构造器需要的参数A,然后把创建C的标识放入当前创建池中。
4:spring创建C需要的A,这个时候会发现在当前创建池中已经有A的标识,A正在创建中则抛出BeanCurrentlyInCreationException。
构造器的循环注入是没有办法解决的,所以只能我们避免.
接下来看下set方式的循环注入:
set方式的循环注入分2种情况,第一种情况是可以解决的循环注入就是单列情况下。第二种情况就是无法解决的循环注入就是多列情况下,下面分析一下原因:
先看第一种情况,还是拿上面的ABC3个类来说明问题,只不过这次不是构造器里面的参数,而是换成他们的成员变量,然后通过set方式类注入,这里代码就不写了直接讲下:
单列下set方式的注入流程是这样的:
1:spring创建A,首先根据其无参构造器创建一个对象A,然后提前暴露出创建出来的这个A对象,然后再当前的创建池中放入创建A的标识,然后进行set方法注入B。
2:spring创建B,首先根据其无参构造器创建一个对象B,然后提前暴露出创建出来的这个B对象,然后在当前的创建池中放入创建B的标识,然后进行set方法的注入C。
3:spring创建C,首先根据其无参构造器创建一个对象C,然后提前暴露出创建处理的这个C对象,然后在当前的创建池中放入创建C的标识,然后进行set方法的注入A。
4:在第三步注入A的时候由于提前暴露出来了创建出来的A对象所以不会报BeanCurrentlyInCreationException的错误。
多列下set方式的循环注入不能解决的原因是在多列的情况下,当创建对象的时候spring不会提前暴露创建处理的对象A,这样的话则会和构造器循环注入出现一样的情况最终导致报错。
解决办法:
去掉最后一层的注入或者中间某一层的注入。通过spring getBean
的方式去获取对象
讲完了。讲的不对的地方谢谢提出来。
来源:https://blog.csdn.net/chengxu2011/article/details/8478290


猜你喜欢
- 将Excel转为PDF格式时,通常情况下转换出来的PDF页面都是默认的宽度大小;如果Excel表格数据的设计或布局比较宽或者数据内较少的情况
- webclient在调用DownloadData或者DownloadString的时候请求回来的数据出现乱码问题,解决办法如下:1、设置we
- 本文实例讲述了Android编程常用技巧。分享给大家供大家参考,具体如下:1. 登录的时候,如果输入有误,则输入框左右震动,表示输入有误在r
- 本文实例为大家分享了Android实现长截屏功能的具体代码,供大家参考,具体内容如下1、MainActivitypublic class M
- @AutoConfiguration读取所有jar包下的 /META-INF/spring.factories 并追加到一个 LinkedM
- 引言CardView是Android 5.0系统之后引入的众多控件之一,实现之后的效果也是比较酷的,它经常被用在RecyclerView和L
- 将BeanFactory和ApplicationContext作为容器使用在Spring中,BeanFactory和ApplicationC
- 一、前言首选,双轴快排也是一种快排的优化方案,在JDK的Arrays.sort()中被主要使用。所以,掌握快排已经不能够满足我们的需求,我们
- 本文较为详细的分析了C#读取二进制文件方法。分享给大家供大家参考。具体分析如下:当想到所有文件都转换为 XML时,确实是一件好事。但是,这并
- MyBatis Plus是一个MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。Mybati
- 项目要用到Webview和js交互,查了查以前的项目感觉还是有必要整理下的。 简单描述下项目中用到的地方,比如说在web页需要用到登录的地方
- 前言本文章主要讲解控制流程:块作用域、条件语句、switch语句,篇幅不大,通俗易记。块作用域在深入学习控制结构前,须先了解块的作用。定义:
- 今天在帮助客户解决一个问题时,由于他们的手机是用的5.0系统身边没有5.0系统的手机,只能用一个模拟器来安装测试应用,但是在安装过程中碰到了
- 1. 什么是单例模式单例模式指的是在应用整个生命周期内只能存在一个实例。单例模式是一种被广泛使用的设计模式。他有很多好处,能够避免实例对象的
- 一.static关键字的用途在《Java编程思想》P86页有这样一段话:“static方法就是没有this的方法。在st
- 导语相信大家无论是做前端还是做后端的,都被接口接口文档所折磨过,前端抱怨接口文档和后端给的不一致,后端抱怨写接口文档很麻烦,所以Swagge
- 本文实例为大家分享了Android本地实现搜索历史记录的具体代码,供大家参考,具体内容如下一.自定义搜索历史记录本地实现搜索历史记录有很多种
- 本文实例为大家分享了OpenCV+Qt实现图像处理操作的具体代码,供大家参考,具体内容如下一、目标Qt界面实现 雪花屏 高斯模糊 中值滤波
- 却被编译器提示说:警告 1“System.Configuration.ConfigurationSettings.AppSettings”已
- 本文实例为大家分享了Android实现信息弹出框的具体代码,供大家参考,具体内容如下layout下的dialog_common_layout