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

标签:spring,循环,注入
0
投稿

猜你喜欢

  • java二维数组指定不同长度实例方法

    2021-07-13 06:02:09
  • Mybatis通过数据库表自动生成实体类和xml映射文件

    2022-01-11 07:05:46
  • java加载properties文件的六种方法总结

    2023-09-20 05:24:54
  • SpringBoot整合activemq的案例代码

    2023-11-06 18:41:37
  • Javassist之一秒理解java动态编程

    2023-11-09 09:36:33
  • java selenium使用浏览器调试工具实现方法

    2023-07-27 04:04:22
  • 基于Java数组实现循环队列的两种方法小结

    2023-06-30 16:09:01
  • Springboot整合MybatisPlus的实现过程解析

    2021-06-14 02:47:06
  • SpringCloud消息总线Bus配置中心实现过程解析

    2023-02-14 10:05:18
  • 10种简单的Java性能优化

    2023-06-20 20:43:41
  • java 排序算法之快速排序

    2022-07-23 17:39:03
  • 详解Java中switch的新特性

    2023-11-24 23:41:54
  • Android仿百度图片查看功能

    2023-09-26 07:50:24
  • java生成图片验证码实例代码

    2022-01-06 04:01:37
  • SpringMVC利用dropzone组件实现图片上传

    2022-01-19 00:37:00
  • 浅谈virtual、abstract方法和静态方法、静态变量理解

    2022-08-29 02:29:14
  • Java虚拟机内存区域划分详解

    2023-06-20 22:04:24
  • SpringBoot启动yaml报错的解决

    2021-09-09 22:58:14
  • mybatis-plus 扩展批量新增的实现

    2023-07-14 14:24:13
  • Java开发环境jdk 1.8安装配置方法(Win7 64位系统/windows server 2008)

    2022-05-11 20:00:58
  • asp之家 软件编程 m.aspxhome.com