【问题标题】:Good practices on finding circular dependencies between spring beans寻找spring bean之间循环依赖的良好实践
【发布时间】:2012-01-14 04:28:42
【问题描述】:

我有这个例外:

SEVERE: Context initialization failedorg.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'myService': Bean with name 'myService' has been injected into other beans [otherService] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.

任何人都可以提出好的策略来找到循环依赖的来源吗?

我目前正在查看上下文定义,但正如您可能想象的那样,在某个成熟的项目中,这需要相当长的时间。

所以我通常在寻找快速找到循环 bean 依赖项的想法。

【问题讨论】:

  • 您是否在配置中使用 XML、注释或配置类?
  • 这里有一篇关于解决的好文章:blog.richardadamdean.com/?p=49
  • 错误信息不是在说 bean otherService 有问题吗? otherService 是否有某种方式依赖于myServicemyService 也依赖于otherService?您是在问如何查看 bean 链接以便检测依赖关系如何循环?
  • @Gray 不,它们不相互依赖。反正不是直接的,这就是我想要找到的。它可能类似于 otherService->3rdService->myservice AND myService->3rdService->otherService。
  • 我最终会通过挖掘上下文找到它,但如果有人知道快速/确定的方法,我会徘徊。

标签: java spring circular-dependency


【解决方案1】:

我知道 OP 的情况不同,但供将来参考:

如果你有这个例外:

  • org.springframework.beans.factory.BeanCurrentlyInCreationException:创建名为“a”的 bean 时出错:当前正在创建请求的 bean:是否存在无法解析的循环引用?

那么堆栈跟踪顶部的消息应该说明依赖循环是什么,例如:

  • org.springframework.beans.factory.UnsatisfiedDependencyException:创建文件 [filename] 中定义的名称为 'a' 的 bean 时出错:通过构造函数参数表示的不满足依赖项,索引为 0,类型为 [ com.gk.simple.B]:在文件 [filename] 中定义的 bean 名称为 'b' 时出错:通过构造函数参数表达的不满足的依赖关系,索引为 0,类型为 [com.gk.simple.A ]:创建 名称为“a”的 bean 时出错:当前正在创建请求的 bean:是否存在无法解析的循环引用?

这里的循环是 a -> b -> a。

【讨论】:

    【解决方案2】:

    对我有用的一种方法是编写一个带有 main 方法的辅助类,该方法实例化可刷新的应用程序上下文,禁止循环依赖并调用刷新。确保您的 bean / app 上下文配置文件位于类路径中。

    public class ContextChecker {
        public static void main( String[] args ) {
            AbstractRefreshableApplicationContext ctx = 
                new ClassPathXmlApplicationContext( "classpath*:/beans.xml" );
            ctx.setAllowCircularReferences( false );
            ctx.refresh();
        }
    }
    

    此类可以作为 Java 应用程序运行,例如从您的 IDE 内部。如果在您的上下文中检测到循环依赖关系,错误消息将提供有关违规 bean 的信息。

    【讨论】:

      【解决方案3】:

      IntelliJ 给了我一个非常好的依赖关系图,尽管我必须增加 Xmx 大小来为操作提供足够的内存。右键单击应用程序上下文文件,Diagrams> Dependency diagram。有时需要一段时间才能加载。如果基于注释的应用上下文不起作用,请尝试将组件扫描移动到 application.xml 并重试。

      【讨论】:

        【解决方案4】:

        这里有 2 个宣传依赖图生成的工具。但是,我对他们没有任何经验。

        【讨论】:

        • 如果您使用其中一个,请在可能的情况下添加有关其工作原理的评论。祝你好运。感谢您的检查。
        • eclipse 的 bean 依赖图很不错,它绘制了非常有用的漂亮图形。您只需向其中一个项目添加一个 spring 项目性质,切换到 spring eclipse 视图,右键单击您的项目,然后单击在您的一个 bean 上绘制依赖关系图。
        猜你喜欢
        • 2018-12-28
        • 2017-04-03
        • 2012-01-14
        • 1970-01-01
        • 1970-01-01
        • 2015-09-27
        • 2021-04-23
        • 2011-06-11
        相关资源
        最近更新 更多