获得Spring循环引用的人类可读输出

时间:2009-06-22 09:16:26

标签: java spring

为了保持理智,我告诉Spring关于循环引用:

    _context = new ClassPathXmlApplicationContext(getApplicationContextFiles(), false);
    _context.setAllowCircularReferences(false);
    _context.refresh();
    _context.start();

问题是生成的堆栈跟踪实际上看起来像barf:|

如何获得循环引用的简单输出,类似于:

Unresolved circular reference: [aBean->nextBean->otherBean->aBean]

3 个答案:

答案 0 :(得分:2)

如果您的所有周期都在注册组件之间,这可能有所帮助(据我所知,您不能轻易引用内部bean,因为它们未注册)。 您可以在bean解析器生成的事件上注册自定义侦听器,为此扩展应用程序上下文并覆盖initBeanDefinitionReader(),在该方法中使用setEventListener在beanDefinitionReader上设置自定义侦听器(您需要转换为XmlBeanDefinitionReader)。

注册ComponentDefinitions时会通知侦听器并将其存储在Map中。 完成配置处理后,您可以使用类似于JDepend的jdepend.framework.JavaPackage来处理ComponentDefinitions以识别周期。 对于每个ComponentDefinition,迭代getBeanDefinitions()和getBeanReferences()(可能还有getInnerBeanDefinitions())并为每个定义添加“JavaPackage”,并为每个引用添加依赖项。 在处理完每个引用和声明之后,您可以查询类似JavaPackage的对象,并为containsCycle()返回任何返回true的结果

答案 1 :(得分:1)

你试过“Spring IDE”吗?它显示了graphical depiction个依赖项。不确定它是否支持基于注释的DI,但它应该......

答案 2 :(得分:1)

我采取的方法是编写一个脚本(可能在Python中,尽管Groovy可能也很合适)来执行以下操作:

  1. 解析bean图形转储的文本以生成形式(A,B)的单个依赖关系的有向图,指示B具有对A的引用。这里A,B等是图中的节点,并且(A,B)配对是边缘。
  2. 在图表上运行拓扑排序。这会在多次传递中删除节点。许多语言都有许多实现。选择一种适合您选择的脚本语言,Google就是您的朋友。
  3. 如果剩下任何节点,则它们是您的循环(循环引用集)。
  4. 听起来有点复杂,但事实并非如此。我已经很多次使用Python脚本解决了类似的问题。