`
jingzhongwen
  • 浏览: 12554 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Spring循环依赖检查算法分析

 
阅读更多

        Spring在注入bean的时候会做循环依赖检查,例如A依赖B,B依赖C,C依赖A,这就形成了一个循环依赖,Spring会抛出异常。

        那么Spring是怎么做到循环依赖检查的呢?我们先来考虑,Spring是如何实现注入功能的,在注入A之前,如果A依赖B那么需要先注入B,然后依次类推下去,明显,这是一个递归的调用,Spring在其BeanFactory的实现类中,对getBean方法递归调用实现注入,代码如下:

// spring 依赖注入 DFS
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
  for (String dependsOnBean : dependsOn) {
    if (isDependent(beanName, dependsOnBean))
   {
     // 有循环依赖,抛异常
   }
   //注册dependsOnBean 的前驱为beanName
    regirsert(dependsOnBean,beanName)
    getBean(dependsOnBean);// 递归调用
  }
}

         如上所示,这其实是一个有向图的深度遍历算法,红色部分实现了循环依赖检查,有兴趣的同学可以自己去看下具体的实现,我这里仅给出形式化解释和伪代码。

        到这里,这个问题就转化为有向图是否存在环的问题。isDependent方法参数传入两个节点,如果有环返回true,否则返回false。我来尝试形式化的描述这个问题的解

有向图环检查形式化描述 写道
->符号记为一个有向的连接
我们尝试连接A->B,那么以下两种情况可判断为有环:
1.如果有B->A,
2.存在某个X->A使B->X。

 算法采用一个map来存某个节点的所有前驱节点,以下是伪代码描述

写道
// 尝试A->B,如果存在B->A返回true
isDependent(String A, String B, Set<String> alreadySeen) {
        if alreadySeen.Has(A) then // 略过所有已访问过的前驱
            return false;
        if map = null then
            return false;
        if map.get(A).has(B) then // 如果有B->A则有环
            return true;
       for X in map.get(A)// 寻找A的所有前驱,X->A
            if isDependent(X,B) then // 如果有B->X则有环
       return true;
       alreadySeen.add(A)// 标记为已访问
       return false;
}

 

0
0
分享到:
评论

相关推荐

    Spring循环依赖debug源码图

    Spring循环依赖debug源码图

    Spring循环依赖.vsdx

    Spring循环依赖.vsdx

    Spring源码最难问题:当Spring AOP遇上循环依赖.docx

    Spring源码最难问题:当Spring AOP遇上循环依赖.docx

    spring bean循环依赖时序图

    spring bean循环依赖时序图详细的描述了spring的循环依赖关系,帮我们快速了解spring是如何优雅的进行处理的

    Spring三级缓存解决循环依赖.pdf

    Spring三级缓存解决循环依赖.pdf

    Spring依赖注入检查.

    Spring依赖注入检查,适合初学者进一步了解Spring框架。

    Spring集成SpringSecurity依赖包

    Spring集成SpringSecurity依赖包.也有springMVC的依赖包,直接下载引入就可用

    spring 2.5依赖包

    spring 2.5依赖包

    3. 循环依赖问题(三级缓存).xmind

    《spring源码之循环依赖和三级缓存》整理,本人水平有限,从网上找的资料整合之后做的,请辩证的看待其中内容。

    Java Maven导入Spring依赖

    Java使用Maven导入Spring依赖

    Spring框架依赖jar包

    Spring框架依赖jar包,其中最小依赖包:org.springframework.core、org.springframework.context、org.springframework.beans、org.springframework.asm、org.springframework.expression、...

    探秘Spring框架解决循环依赖的高效策略

    Spring框架作为Java企业级应用的核心,其解决循环依赖的能力是其健壮性和灵活性的关键体现。循环依赖,即两个或多个组件相互依赖,常在大型应用中遇见。Spring通过三级缓存和AOP代理机制巧妙处理这一挑战。首先,一...

    spring aop依赖jar包

    springaop依赖的jar包,spring版本2.5.6,如果需要,可以下载使用,欢迎各位评论指出不足

    Spring 相关依赖包

    Spring相关依赖包,(spring-framework-3.0.2.RELEASE-dependencies)

    简单了解Spring循环依赖解决过程

    主要介绍了简单了解Spring循环依赖解决过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    spring13: spring 循环依赖

    1. 循环依赖检查 无论单例还是原型模式(下文①代表图中步骤1),spring都有对应的集合保存当前正在创建的beanName,标识该beanName正在被创建。在bean创建前,①检测当前bean是否在创建中,如果不在创建中则②将...

    理解Spring循环依赖.docx

    在开发中,可能经常出现这种情况,只是我们平时并没有注意到原来我们写的两个类、甚至多个类相互依赖了,为什么注意不到呢?...这一切都是Spring的功劳,它在后面默默的为我们解决了循环依赖的问题。

    详解Spring循环依赖的解决方案

    主要介绍了详解Spring循环依赖的解决方案,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    Spring 解决循环依赖的 3 种方式.docx

    第一种:构造器参数循环依赖 Spring容器会将每一个正在创建的Bean 标识符放在一个“当前创建Bean池”中,Bean标识符在创建过程中将一直保持在这个池中。 因此如果在创建Bean过程中发现自己已经在“当前创建Bean池”...

    Spring MVC依赖包

    Spring mvc依赖包 Spring mvc都做了些什么 Controller为中心完成对系统流程的控制管理 从请求中搜集数据 对传入的参数进行验证 将结果返回给视图 针对不同的视图提供不同的解决方案 针对jsp视图技术提供标签库 拦截...

Global site tag (gtag.js) - Google Analytics