- 浏览: 1466379 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
luhouxiang:
写的很不错,学习了
Extjs 模块化动态加载js实践 -
kingkongtown:
如果想改成淘宝后台那样,可以在编辑器批量上传图片呢?
kissy editor 阶段体会 -
317966578:
兄弟我最近也在整jquery和caja 开放一些接口。在git ...
caja 原理 : 前端 -
liuweihug:
Javascript引擎单线程机制及setTimeout执行原 ...
setTimeout ,xhr,event 线程问题 -
辽主临轩:
怎么能让浏览器不进入 文档模式的quirks模式,进入标准的
浏览器模式与文本模式
循环依赖是和语言无关的一个设计问题,在各个语言环境下都可能存在循环依赖,甚至引起 stackoverflow,这种大多数是由于不好的设计而导致的,一般来说都可以通过提取公共模块而解决,特定的场景下对应用程序做一定的调整也可以在维持循环依赖的前提下避免栈溢出。
语言机制:
c++
c++ 中的循环类定义引用会导致编译出错,一般的解决方案可以通过提前声明来解决:
b.h class A; class B { A a; } a.h class B; class A { B b }
java
java 不需要像 C++ 一样提前声明,其中的循环依赖一般指两个类中实例变量的循环初始化,例如:
class A { B b=new B(); } class B { A a =new A(); }
但是有了 spring 就可以很方便地通过依赖反转来解决这个问题,对应用代码做少许改变:
class A{ B b; void setB(B b){this.b=b;} } class B{ A a; void setB(A a){this.a=a;} }
将依赖信息告诉 spring,spring 会设置好两个类实例的对应成员变量(先初始化实例再依赖注入)。
python
循环依赖指模块间的循环 import ,模块间互相使用对方的功能,在某些情景下其实可以通过调整引用顺序而避免引用不到对应模块的功能。
x.py import y def z(): y.xx(); def q(): // y.py import x x.q() //=> 没有 q
可以看到 y 的初始化需要立即使用 x模块的功能,而 x 模块初始化并不立即需要 y 模块功能,那么可以通过调整 x 模块中 y 模块的引入位置来避免初始化依赖而导致的空函数
x.py def z(): y.xx(); def q(): // import y
javascript
javascript 没有原生的模块机制,如果遵从 commonjs modules/1.1.1 ,那么面临和 python 一样的问题:
// a .js define(function(require,exports){ var b=require("b"); exports.z=function(){ b.z(); } exports.y=function(){} }) // b.js define(function(require,exports){ var a=require("a"); exports.z=function(){}; expots.x=a.y(); })
这种情况下的解决也是类似的调整代码顺序:
// a .js define(function(require,exports){ exports.z=function(){ b.z(); } exports.y=function(){} var b=require("b"); })
而对于 amd (requirejs , kissy ) 形式的模块则无论哪种形式的循环引用都不可能通过简单的调整代码顺序来解决:
// a .js define(["b"],function(b){ var ret={}; ret.z=function(){ b.z(); } ret.y=function(){} return ret; }) // b.js define(["a"],function(a){ var ret={}; ret.z=function(){}; ret.x=a.y(); return ret; })
循环依赖检测
程序中出现循环依赖是一种坏味道,所以在出现循环依赖时都希望语言实现以及模块框架能够及时提示,对于客户端的动态加载代码场景,js 的检测方法又有点特殊。
静态循环检测
一般的循环检测是有向图的一个常见问题,最常用的是 floyd 算法,而这种算法的前提是整个依赖图已经都全部知道,而对于 js 模块代码的依赖则是边下载模块脚本边构造模块的依赖图,没有机会等依赖图全部建立好后再进行静态循环分析(存在循环以来时,依赖图实际上永远也建立不好)。
动态循环检测
对于静态循环依赖检测,floyd 算法在空间和时间两方面都取得了很好的效果,这里提出的在构建依赖图的同时动态检测循环依赖的算法难免在空间方面有所不足。
前提:
模块 a 的初始化需要在 a 的所有依赖模块初始化之后。
步鄹:
对每个模块构建 map 结构 all_requires 表示当前模块的所有递归依赖项的集合,那么
1. 初始条件下 all_requires 为空 map
2. 在两种情况下扩充 all_requires
2.1 当前模块 a 下载完毕,取得 a 的直接依赖集合 bs,合并 bs 到 all_requires
2.2 由于模块 b 的初始化而导致作为 b 的依赖模块 a 的初始化:将模块 a 的直接依赖集合 bs 中每个模块的 all_requires 都合并到 a 的 all_requires 中
3. 检测当前模块 a 的 all_requires 集合中是否包含 a
3.1 包含,则 a 的 all_requires 集合中的所有模块形成了循环依赖
4. 如果 a 初始化后,a 的 all_requires 仍然没有包含 a ,则 a 不在某个循环依赖模块集合中。
举例:
a -> b -> c -> a
初始 all_requires 集合:
a : {}
b: {}
c: {}
下载 a 后:
a:{b}
b:{}
c:{}
下载 b 后
a:{b}
b:{c}
c:{}
下载 c 后
a:{b}
b:{c}
c:{a}
c 导致 a 初始化
a:{bc}
b:{c}
c:{a}
a 导致 b 初始化
a:{bc}
b:{ca}
c:{a}
b 导致 c 初始化
a:{bc}
b:{ca}
c:{abc}
结束:
c 发现自己处于 abc 循环依赖中,报错
算法复杂度分析:
时间复杂度为 o(l), l 为循环依赖模块集合的大小
空间复杂度比较高,为 o(l^2) ,每个模块的 all_requires 集合都包含了近似于所有循环依赖的模块。
Refer:
http://en.wikipedia.org/wiki/Cycle_detection
http://en.wikipedia.org/wiki/Circular_dependency
http://effbot.org/zone/import-confusion.htm
http://stackoverflow.com/questions/3646113/circular-dependency-in-java-classes
http://stackoverflow.com/questions/3485347/circular-dependency-in-spring
http://java.dzone.com/articles/tackling-circular-dependency
发表评论
-
构建前端 DSL
2012-10-11 22:10 5375目前在传统的软件开 ... -
write html parser
2011-12-01 02:48 2928首先需要声明 html 不能用正则表达式来直接匹配进行内容抽取 ... -
转载:瀑布流布局浅析
2011-09-29 19:02 2856简介 如果你经 ... -
循环引用下的深度克隆
2011-08-04 20:39 2332深度复制和浅度复制 是当初初学 c 遇到的第一批问题,似乎使 ... -
读书笔记:整数位表示
2011-03-06 22:55 1703From : Computer System ( A Prog ... -
firebug 1.6 更新功能
2010-11-30 20:21 4154来源:firebug 1.6 release note ... -
google's tricks
2010-09-09 13:17 2205最近一直沉迷在 ant 神奇的自动化中,对于外界很迟钝,但 ... -
开关状态信息的保存
2010-08-30 15:23 1688系统中常常会存在大量的状态信息,特别是0-1值信息,某个条件是 ... -
idea setting
2010-07-09 18:04 0idea setting for web develop -
web开发综合技术
2010-06-23 23:36 0在这个 Web 的时代,与 W ... -
shell mhr
2010-06-08 23:36 0#example # mj.sh /root/w ... -
www.ascampus.com 建议
2010-06-04 11:41 0系统消息(1000)2010-06-04 11:27:01 ... -
shell的命令替换与eval
2010-05-29 22:43 4934学习 shell 中遇到了 shell ... -
openVPN相关网络
2010-05-24 03:15 0http://blog.chinaunix.net/u/104 ... -
twitter follow
2010-05-19 02:27 0、Twitter每日推荐一位推友计划 (第一季)中的推友名单 ... -
python作用域问题
2010-04-27 10:44 0作用域 手边的《python技术参考大全》(python: ... -
翻~墙指南
2010-04-17 14:35 0讨厌上个网还这么麻烦,但想看看 youtube 上 c ... -
LL文法算法-1
2010-03-12 22:30 3481为了实现自顶向下的语法分析器,需要将文法的 1.左递归消 ... -
NFA到DFA的转换演示
2010-03-07 20:57 12736复习一下编译,在龙书中提到的NFA(不确定有穷自动机)到D ... -
试用 git
2010-02-18 15:00 2762在初步看完 pro git 后,很被 git 的分布式仓库设 ...
相关推荐
Circular dependency detected(解决方案).md
Dependency Walker detects many common application problems such as missing modules, invalid modules, import/export mismatches, circular dependency errors, mismatched machine types of modules, and ...
Dependency Walker detects many common application problems such as missing modules, invalid modules, import/export mismatches, circular dependency errors, mismatched machine types of modules, and ...
循环类依赖软件测试项目,2015 年Spring检测Java类中循环依赖的Java程序
1. 构造器参数循环依赖(Constructor-based circular dependency) 这是描述中提到的第一种方式。当Spring检测到构造器参数中的循环依赖时,它会使用“三级缓存”机制来解决。这个机制包括以下三个缓存: - ...
在IT行业中,循环依赖(Circular Dependency)是一个常见的问题,尤其在后端开发中。"LCC"在这里可能指的是"Loop-Closure Constraint"或者某种特定的处理循环依赖的机制。在这个"lcc循环依赖"的重磅资料中,我们可以...
本资源"spring-learn.zip"显然是一份关于学习Spring框架的资料,特别是聚焦于循环依赖(Circular Dependency)这一主题。循环依赖是编程中常见的问题,尤其是在依赖注入(Dependency Injection,DI)框架如Spring中...
在Spring框架中,循环依赖(Circular Dependency)是指两个或多个bean之间形成了一种相互引用的关系,使得它们在初始化过程中无法独立完成实例化。在上述案例中,`AuthorService`依赖于`BookService`,而`...
在 Spring 中,循环依赖(Circular Dependency)和三级缓存是两个重要的概念,尤其在面试和技术探讨中经常被提及。本文将深入探讨这两个主题,帮助你彻底理解它们。\n\n首先,让我们定义什么是循环依赖。在 Java ...
在实际应用中,我们需要谨慎设计关联关系,避免循环引用(Circular Dependency),这可能导致内存泄漏或者懒加载陷阱。同时,为了优化性能,我们可能需要调整关联的加载策略,比如使用懒加载(Lazy Loading)避免...
The CloudFormation template is invalid: Circular dependency between resources: [ApiGatewayUsagePlanKey2, ApiGatewayUsagePlanKey1, WebrtcNestedStack, ApiGatewayDeployment1528886435994, ...
人力资源管理系统 (HRMS) 后端想要 :fire: 要求 1:求职者应该能够在系统中注册。 接受条件: ... :rainbow: 各个领域都需要。 通知用户。... :rainbow: 如果验证无效,则通知用户。... :rainbow: 如果有以前
“循环加载”(circular dependency)指的是,a脚本的执行依赖b脚本,而b脚本的执行又依赖a脚本。 // a.js var b = require('b'); // b.js var a = require('a'); 通常,”循环加载”表示存在强耦合,如果处理不好...
另一个项目填补了我直到找到实习职位的时间。 具有身份验证功能的完整Crud Mern堆栈...(node:25647) Warning: Accessing non-existent property 'MongoError' of module exports inside circular dependency Server
循环依赖插件与webpack捆绑时,检测具有循环依赖性的模块。 循环依赖关系在复杂软件中通常是必需的,...基本用法// webpack.config.jsconst CircularDependencyPlugin = require ( 'circular-dependency-plugin' )mod
5. **循环依赖(Circular Dependency)**:模块间的相互依赖形成环状,可能导致系统结构混乱,增加耦合度。 6. **硬编码(Hard Coding)**:将值直接写入代码中,不易于更改和维护,可能导致安全问题。 7. **过度设计...
在Spring框架中,循环引用(Circular Dependency)是一个常见的问题,特别是在使用依赖注入(Dependency Injection)时。本篇文章将深入分析Spring如何处理循环引用,并通过源码解析其内部机制。 首先,我们来理解...
在AXXX module中api project(':BXXX'),而在BXXX module中api project(':AXXX'),这样出现了相互依赖,编译器会出现Circular dependency,循环相互依赖的问题。 为了解决上述的问题,将AXXX module与BXXX module...
在Spring框架中,循环依赖(Circular Dependency)是一个常见的问题,特别是在复杂的系统中。Spring通过其强大的依赖注入(Dependency Injection,DI)机制,有效地解决了这个问题。本文将深入探讨Spring如何处理...
在Spring框架中,循环依赖(Circular Dependency)是指两个或多个Bean之间形成的一种相互依赖关系,导致Spring容器在初始化这些Bean时遇到困难。当一个Bean依赖于另一个Bean,而后者又反过来依赖于前者,就会出现...