我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java中的Spring怎么处理循环依赖

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java中的Spring怎么处理循环依赖

这篇“Java中的Spring怎么处理循环依赖”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Java中的Spring怎么处理循环依赖”文章吧。

什么是循环依赖

依赖指的是Bean与Bean之间的依赖关系,循环依赖指的是两个或者多个Bean相互依赖,

构造器循环依赖

代码示例:

public class BeanA {    private BeanB beanB;    public BeanA(BeanB beanB){        this.beanB = beanB;    }}public class BeanB {    private BeanA beanA;    public BeanB(BeanA beanA){        this.beanA = beanA;    }}

配置文件:

<bean id="beanA" class="cn.itsource._01_di.BeanA" >        <constructor-arg type="cn.itsource._01_di.BeanB" ref="beanB"  /> </bean> <bean id="beanB" class="cn.itsource._01_di.BeanB"  >         <constructor-arg type="cn.itsource._01_di.BeanA" ref="beanA" /> </bean>

Setter循环依赖

代码示例:

public class BeanA {    private BeanB beanB;    public void setBeanB(BeanB beanB){        this.beanB = beanB;    }}@Datapublic class BeanB {    private BeanA beanA;    public void setBeanA(BeanA beanA){        this.beanA = beanA;    }}

配置文件

<bean id="beanA" class="cn.itsource._01_di.BeanA" >    <property name="beanB" ref="beanB" /></bean><bean id="beanB" class="cn.itsource._01_di.BeanB">    <property name="beanA" ref="beanA" /></bean>

循环依赖包括: 构造器注入循环依赖 set , 注入循环依赖 和 prototype模式Bean的循环依赖。Spring只解决了单例Bean的 setter 注入循环依赖,对于构造器循环依赖,和 prototype模式的循环依赖是无法解决的,在创建Bean的时候就会抛出异常 :“BeanCurrentlyInCreationException” ,

循环依赖控制开关在 AbstractRefreshableApplicationContext 容器工厂类中有定义:

public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext { @Nullable private Boolean allowBeanDefinitionOverriding; //是否允许循环依赖 @Nullable private Boolean allowCircularReferences; //设置循环依赖 public void setAllowCircularReferences(boolean allowCircularReferences) {  this.allowCircularReferences = allowCircularReferences; }

默认情况下是允许Bean之间的循环依赖的,在依赖注入时Spring会尝试处理循环依赖。如果将该属性配置为“false”则关闭循环依赖,当在Bean依赖注入的时遇到循环依赖时抛出异常。可以通过如下方式关闭,但是一般都不这么做

ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");//禁用循环依赖applicationContext.setAllowCircularReferences(false);//刷新容器applicationContext.refresh();...

构造器循环依赖处理

构造器是不允许循环依赖的,动动你的小脑瓜想一想,比如:A 依赖 B ,B依赖C,C依赖A,在实例化A的时候,构造器需要注入B,然后Spirng会实例化B,此时的A属于“正在创建”的状态。当实例化B的时候,发现构造器需要注入C,然后去实例化C,然而实例化C的时候又需要注入A的实例,这样就造成了一个死循环,永远无法先实例化出某一个Bean,所以Spring遇到这里构造器循环依赖会直接抛出异常。

那么Spring到底是如何做的呢?

  • 首先Spring会走Bean的实例化流程尝试创建 A 的实例 ,在创建实例之间先从 “正在创建Bean池” (一个缓存Map而已)中去查找A 是否正在创建,如果没找到,则将 A 放入 “正在创建Bean池”中,然后准备实例化构造器参数 B。

  • Spring会走Bean的实例化流程尝试创建 B 的实例 ,在创建实例之间先从 “正在创建Bean池” (一个缓存Map而已)中去查找B 是否正在创建,如果没找到,则将 B 放入 “正在创建Bean池”中,然后准备实例化构造器参数 A。

  • Spring会走Bean的实例化流程尝试创建 A 的实例 ,在创建实例之间先从 “正在创建Bean池” (一个缓存Map而已)中去查找A 是否正在创建。

  • 此时:Spring发现 A 正处于“正在创建Bean池”,表示出现构造器循环依赖,抛出异常:“BeanCurrentlyInCreationException”

DefaultSingletonBeanRegistry#getSingleton

下面我们以 BeanA 构造参数依赖BeanB, BeanB 构造参数依赖BeanA 为例来分析。

当Spring的IOC容器启动,尝试对单利的BeanA进行初始化,根据之前的分析我们知道,单利Bean的创建入口是 AbstractBeanFactory#doGetBean 在该方法中会先从单利Bean缓存中获取,如果没有代码会走到:DefaultSingletonBeanRegistry#getSingleton(jString beanName, ObjectFactory<?> singletonFactory) 方法中 ,在该方法中会先对把创建的Bean加入 一个名字为 singletonsCurrentlyInCreation 的 ConcurrentHashMap中,意思是该Bean正在创建中,然后调用 ObjectFactory.getObject() 实例化Bean , 假设 BeanA 进入了该方法进行实例化:

//正在创建中的Beanprivate final Set<String> singletonsCurrentlyInCreation =   Collections.newSetFromMap(new ConcurrentHashMap<>(16));public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {  ...省略...  //把该Bean的名字加入 singletonsCurrentlyInCreation 正在创建池 中  beforeSingletonCreation(beanName);  boolean newSingleton = false;  boolean recordSuppressedExceptions = (this.suppressedExceptions == null);  if (recordSuppressedExceptions) {   this.suppressedExceptions = new LinkedHashSet<>();  }  try {   //调用ObjectFactory创建Bean的实例   singletonObject = singletonFactory.getObject();   newSingleton = true;  }...省略...//如果singletonsCurrentlyInCreation中没该Bean,就把该Bean存储到singletonsCurrentlyInCreation中,//如果 singletonsCurrentlyInCreation 中有 该Bean,就报错循环依赖异常BeanCurrentlyInCreationException//也就意味着同一个beanName进入该方法2次就会抛异常protected void beforeSingletonCreation(String beanName) {  if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {   throw new BeanCurrentlyInCreationException(beanName);  } }

beforeSingletonCreation 方法非常关键 ,它会把beanName加入 singletonsCurrentlyInCreation,一个代表“正在创建中的Bean”的ConcurrentHashMap中。

如果singletonsCurrentlyInCreation中没该beanName,就把该Bean存储到singletonsCurrentlyInCreation中, 如果 singletonsCurrentlyInCreation 中有 该Bean,就报错循环依赖异常BeanCurrentlyInCreationException

【注意】也就意味着同一个beanName进入该方法2次就会抛异常 , 现在BeanA已经加入了singletonsCurrentlyInCreation

AbstractAutowireCapableBeanFactory#autowireConstructor

我们前面分析过 ObjectFactory.getObject实例化Bean的详细流程,这里我只是大概在复盘一下就行了。因为我们的BeanA的构造器注入了一个BeanB,所以 代码最终会走到AbstractAutowireCapableBeanFactory#autowireConstructor ,通过构造器来实例化BeanA(在属性注入那一章有讲到 ) 。

在autowireConstructor 方法中会通过 ConstructorResolver#resolveConstructorArguments来解析构造参数,调用 BeanDefinitionValueResolver 去把 ref="beanB" 这种字符串的引用变成一个实实在在的Bean,即BeanB,所以在 BeanDefinitionValueResolver 属性值解析器中又会去实例化BeanB,同样会走到 DefaultSingletonBeanRegistry#getSingleton 中把BeanB加入 singletonsCurrentlyInCreation “正在创建Bean池”中,然后调用ObjectFactory.getObject实例化BeanB。

低于BeanB而已同样需要通过构造器创建,BeanB构造器参数依赖了BeanA,也就意味着又会调用 BeanDefinitionValueResolver 去把 ref=“beanA” 这种字符串引用变成容器中的BeanA的Bean实例,然后代码又会走到 DefaultSingletonBeanRegistry#getSingleton。然后再一次的尝试把BeanA加入singletonsCurrentlyInCreation “正在创建Bean池”。

此时问题就来了,在最开始创建BeanA的时候它已经加入过一次“正在创建Bean” 池,这会儿实例化BeanB的时候,由于构造器参数依赖了BeanA,导致BeanA又想进入“正在创建Bean” 池 ,此时 Spring抛出循环依赖异常:

Error creating bean with name &lsquo;beanA&rsquo;: Requested bean is currently in creation: Is there an unresolvable circular reference?

到这,Spring处理构造器循环依赖的源码分析完毕。

setter循环依赖处理

setter循环依赖是可以允许的。Spring是通过提前暴露未实例化完成的Bean的 ObjectFactory来实现循环依赖的,这样做的目的是其他的Bean可以通过 ObjectFactory 引用到该Bean。

实现流程如下:

  • Spring创建BeanA,通过无参构造实例化,把BeanA添加到“正在创建Bean池”中,并暴露当前实例的ObjectFactory,即把ObjectFactory添加到singletonFactories(三级缓存)中,该ObjectFactory用来获取创建中的BeanA,然后,然后通过setter注入BeanB

  • Spring创建BeanB,通过无参构造实例化,把BeanB添加到“正在创建Bean池”中,并暴露一个ObjectFactory,然后,然后通过setter注入BeanA

  • 在BeanB通过setter注入BeanA时,由于BeanA 提前暴露了ObjectFactory ,通过它返回一个提前暴露一个创建中的BeanA。

  • 然后完成BeanB的依赖注入

获取Bean的时候走三级缓存:

 protected Object getSingleton(String beanName, boolean allowEarlyReference) {     //一级缓存,存储实例化好的Bean  Object singletonObject = this.singletonObjects.get(beanName);  //如果单利缓存池中没有,但是beanName正在创建  if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {   synchronized (this.singletonObjects) {       //获取二级缓存,这个里面存储的是正在创建的Bean,半成品    singletonObject = this.earlySingletonObjects.get(beanName);     //如果也为空,但是允许循环依赖    if (singletonObject == null && allowEarlyReference) {     //从三级缓存获取Bean的创建工厂,     ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);     if (singletonFactory != null) {        //创建Bean的实例      singletonObject = singletonFactory.getObject();      //把Bean存储到二级缓存      this.earlySingletonObjects.put(beanName, singletonObject);       //移除三级缓存中的创建工厂      this.singletonFactories.remove(beanName);     }    }   }  }  return (singletonObject != NULL_OBJECT ? singletonObject : null); }

AbstractAutowireCapableBeanFactory#doCreateBean

我们以BeanA 通过settter依赖BeanB,BeanB通过setter 依赖BeanA为例来分析一下源码,在之前的Bean实例化流程分析过程中我们了解到,Bean的实例化会走AbstractBeanFactory#doGetBean,然后查找单利缓存中是否有该Bean ,如果没有就调用 DefaultSingletonBeanRegistry#getSingleton,方法会把BeanA加入 singletonsCurrentlyInCreation “创建中的Bean池”,然后调用ObjectFactory.getObject创建Bean.

org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean 源码:

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,   @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {  final String beanName = transformedBeanName(name);  Object bean;  // Eagerly check singleton cache for manually registered singletons.  //缓存中获取Bean,解决了循环依赖问题  Object sharedInstance = getSingleton(beanName);      ...缓存中没有走下面...  if (mbd.isSingleton()) {     //走 DefaultSingletonBeanRegistry#getSingleton ,方法会把bean加入“正在创建bean池”     //然后调用ObjectFactory实例化Bean     sharedInstance = getSingleton(beanName, () -> {      try {       return createBean(beanName, mbd, args);      }      catch (BeansException ex) {       // Explicitly remove instance from singleton cache: It might have been put there       // eagerly by the creation process, to allow for circular reference resolution.       // Also remove any beans that received a temporary reference to the bean.       destroySingleton(beanName);       throw ex;      }     });     bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);    }

第一次进来,缓存中是没有BeanA的,所有会走 getSingleton 方法,然后代码最终会走到AbstractAutowireCapableBeanFactory#doCreateBean 方法中 。

AbstractAutowireCapableBeanFactory#doCreateBean源码:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)   throws BeanCreationException {  // Instantiate the bean.  BeanWrapper instanceWrapper = null;  if (mbd.isSingleton()) {   instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);  }  if (instanceWrapper == null) {  //实例化Bean   instanceWrapper = createBeanInstance(beanName, mbd, args);  }  ...省略...  //如果是单利 ,如果是允许循环依赖,如果 beanName 出于创建中,已经被添加到“创建中的bean池”boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&    isSingletonCurrentlyInCreation(beanName));  if (earlySingletonExposure) {   if (logger.isDebugEnabled()) {    logger.debug("Eagerly caching bean '" + beanName +      "' to allow for resolving potential circular references");   }   //把ObjectFactory 添加到 singletonFactories 中。   addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));  } try {  //走依赖注入流程   populateBean(beanName, mbd, instanceWrapper);   exposedObject = initializeBean(beanName, exposedObject, mbd);  }//缓存单利Bean的创建工厂,用于解决循环依赖protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {  Assert.notNull(singletonFactory, "Singleton factory must not be null");  synchronized (this.singletonObjects) {   //singletonObjects单利缓存中是否包含Bean   if (!this.singletonObjects.containsKey(beanName)) {    //提前暴露ObjectFactory,把ObjectFactory放到singletonFactories中,    //后面解决循环依赖,获取Bean实例的时候会用到    this.singletonFactories.put(beanName, singletonFactory);    //早期单利bean缓存中移除Bean    this.earlySingletonObjects.remove(beanName);    //把注册的Bean加入registeredSingletons中    this.registeredSingletons.add(beanName);   }  } }

该方法中把BeanA实例化好之后,会把ObjectFactory存储到一个 singletonFactories(HashMap)中来提前暴露Bean的创建工厂,用于解决循环依赖【重要】,然后调用 populateBean 走属性注入流程。

属性注入会通过BeanDefinition得到bean的依赖属性,然后调用 AbstractAutowireCapableBeanFactory#applyPropertyValues ,把属性应用到对象上。在applyPropertyValues 方法中最终调用 BeanDefinitionValueResolver#resolveValueIfNecessary 解析属性值,比如:ref=“beanB” 这种字符串引用变成 对象实例的引用。

在BeanDefinitionValueResolver解析依赖的属性值即:BeanB的时候,同样会触发BeanB的实例化,代码会走到AbstractBeanFactory#doGetBean ,然后走方法 DefaultSingletonBeanRegistry#getSingleton 中把BeanB加入 singletonsCurrentlyInCreation “创建中的Bean池”,然后代码会走到AbstractAutowireCapableBeanFactory#doCreateBean 方法中创建BeanB,

该方法中会先实例化BeanB,接着会把BeanB的ObjectFactory存储到 singletonFactories (HashMap)中来提前暴露Bean的创建工厂,用于解决循环依赖,然后调用 populateBean 走属性注入流程。

同样因为BeanB通过Setter 注入了 A,所以在 populateBean 属性注入流程中会解析 ref=“beanA” 为容器中的 BeanA 的实例。

然后会走到 AbstractBeanFactory#doGetBean 中获取BeanA的实例。这个时候流程就不一样了,我们先看一下 AbstractBeanFactory#doGetBean 中的代码

protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,   @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {  final String beanName = transformedBeanName(name);  Object bean;  // Eagerly check singleton cache for manually registered singletons.  //从缓存中获取Bean  Object sharedInstance = getSingleton(beanName);  ...省略...  //如果缓存中没有Bean,就创建Bean  if (mbd.isSingleton()) {     sharedInstance = getSingleton(beanName, () -> {      try {       return createBean(beanName, mbd, args);      }      catch (BeansException ex) {       // Explicitly remove instance from singleton cache: It might have been put there       // eagerly by the creation process, to allow for circular reference resolution.       // Also remove any beans that received a temporary reference to the bean.       destroySingleton(beanName);       throw ex;      }     });     bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);    }

在获取单利Bean的实例的时候是会先去单利Bean的缓存中去查看Bean是否已经存在,如果不存在,才会走DefaultSingletonBeanRegistry#getSingleton方法创建Bean。

问题是:此刻单利Bean缓存中已经有BeanA了,因为在最开始BeanA已经出于“正在创建Bean池”中了。我们先来看一下是如何从缓存获取Bean的。

DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)源码如下:

//allowEarlyReference :是否创建早期应用,主要用来解决循环依赖 @Nullable protected Object getSingleton(String beanName, boolean allowEarlyReference) {  // Quick check for existing instance without full singleton lock  //从Map中 singletonObjects = new ConcurrentHashMap<>(256); 获取单利Bean  //【一级缓存】singletonObject缓存中是否有Bean , 它存储的是已经实例化好的Bean  Object singletonObject = this.singletonObjects.get(beanName);  //如果singletonObjects中没有Bean,但是Bean出于正在创建池中,即:Set<String> singletonsCurrentlyInCreation中有Bean,  if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {   //【二级缓存】从早期单例对象的缓存 earlySingletonObjects 中获取   singletonObject = this.earlySingletonObjects.get(beanName);   //早期单利对象缓存中也没有,但是允许循环依赖   if (singletonObject == null && allowEarlyReference) {    synchronized (this.singletonObjects) {     // Consistent creation of early reference within full singleton lock     singletonObject = this.singletonObjects.get(beanName);     if (singletonObject == null) {      singletonObject = this.earlySingletonObjects.get(beanName);      if (singletonObject == null) {       //【三级缓存】获取ObjectFactory , 对象创建工厂,得到Bean创建过程中提前暴露的工厂。       ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);       if (singletonFactory != null) {        //通过工厂ObjectFactory 获取对象实例        singletonObject = singletonFactory.getObject();        //把对象存储到早期缓存中        this.earlySingletonObjects.put(beanName, singletonObject);        //把ObjectFactory移除        this.singletonFactories.remove(beanName);       }      }     }    }   }  }  return singletonObject; }

这里就是经典的三级缓存解决Spring循环依赖。你看到了,这里会先从 singletonObjects 单利Bean缓存集合中获取Bean(该缓存是实例化完成了的Bean),如果没有,就从earlySingletonObjects早期对象缓存中获取Bean(该缓存中存放的是还未实例化完成的早期Bean),如果还是没有,就从singletonFactories中得到暴露的ObjectFactory来获取依赖的Bean。然后放入早期缓存中。并把ObjectFactory从singletonFactories中移除。最后返回Bean的实例。

由于在实例化BeanA的时候已经把BeanA的ObjectFactory添加到了 singletonFactories 缓存中,那么这里就会走到 singletonFactory.getObject(); 方法得到BeanA的实例,并且会把BeanA存储到 earlySingletonObjects早期单利Bean缓存中。

BeanA的实例成功返回,那么BeanB的 setter注入成功,代表BeanB实例化完成,那么BeanA的setter方法注入成功,BeanA实例化完成。

prototype模式的循环依赖

对于prototype模式下的Bean不允许循环依赖,因为 这种模式下Bean是不做缓存的,所以就没法暴露ObjectFactory,也就没办法实现循环依赖。

以上就是关于“Java中的Spring怎么处理循环依赖”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java中的Spring怎么处理循环依赖

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java中的Spring怎么处理循环依赖

这篇“Java中的Spring怎么处理循环依赖”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Java中的Spring怎么处理
2023-06-30

怎么理解java中Spring循环依赖

这篇文章主要介绍“怎么理解java中Spring循环依赖”,在日常操作中,相信很多人在怎么理解java中Spring循环依赖问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么理解java中Spring循环依赖
2023-06-16

Spring中怎么处理循环依赖问题

Spring中怎么处理循环依赖问题,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。什么是循环依赖依赖指的是Bean与Bean之间的依赖关系,循环依赖指的是两个或者
2023-06-20

怎么理解Spring循环依赖

本篇内容介绍了“怎么理解Spring循环依赖”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!通常来说,如果问Spring内部如何解决循环依赖,
2023-06-16

Spring中的循环依赖

目录 一、什么是循环依赖?二、Bean的生命周期2.1 Spring Bean 的生命周期2.2 Bean 的生成步骤 三、三级缓存3.1三个缓存分别有什么作用 四、思路分析4.1 为什么 Spring 中还需要 singl
2023-08-16

Java中的Spring循环依赖实例分析

这篇文章主要讲解了“Java中的Spring循环依赖实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java中的Spring循环依赖实例分析”吧!什么是循环依赖?很简单,就是A对象依赖
2023-06-30

Spring Boot循环依赖怎么解决

本文小编为大家详细介绍“Spring Boot循环依赖怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“Spring Boot循环依赖怎么解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。什么是循环依赖?循
2023-07-05

MyBatis iterate的循环依赖处理

MyBatis 的 iterate 循环依赖处理主要涉及到以下几点:使用 resultMap:在 MyBatis 中,可以使用 resultMap 来映射查询结果集到 Java 对象。当遇到循环依赖时,可以通过在 resultMap 中使用
MyBatis iterate的循环依赖处理
2024-09-22

Spring循环依赖问题怎么解决

在Spring中,循环依赖问题是指两个或多个bean之间出现相互依赖的情况。由于Spring容器默认使用单例模式管理bean,因此循环依赖可能导致bean无法正确创建。解决Spring循环依赖问题,可以尝试以下方法:1. 避免使用构造函数注
2023-08-31

怎么在spring中解决循环依赖问题

怎么在spring中解决循环依赖问题?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。setter singleton循环依赖使用SingleSetterBeanA依赖Sing
2023-06-08

Java项目中怎么避免循环依赖

本篇文章给大家分享的是有关Java项目中怎么避免循环依赖,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。举个例子:图中我们的API 库导入了一些库,但这些库同时依赖了库X的不同版
2023-06-15

Spring处理@Async导致的循环依赖失败问题怎么解决

本文小编为大家详细介绍“Spring处理@Async导致的循环依赖失败问题怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“Spring处理@Async导致的循环依赖失败问题怎么解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入
2023-07-02

Spring源码是怎么解决Bean的循环依赖

这篇文章给大家分享的是有关Spring源码是怎么解决Bean的循环依赖的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。首先需要明白一点,只有scop为(singleton)单例类型的Bean,spring才支持循环
2023-06-22

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录