繁体   English   中英

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

[英]Getting human-readable output of Spring circular references

为了保持理智,我告诉Spring要在循环引用上做准备:

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

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

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

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

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

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

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

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

  1. 解析bean图形转储的文本以生成形式(A,B)的单个依赖关系的有向图,指示B具有对A的引用。这里A,B等是图中的节点,并且(A ,B)配对是边缘。
  2. 在图表上运行拓扑排序。 这会在多次传递中删除节点。 许多语言都有许多实现。 选择一种适合您选择的脚本语言,Google就是您的朋友。
  3. 如果剩下任何节点,它们就是你的循环(循环引用集)。

听起来有点复杂,但实际上并非如此。 我已经很多次使用Python脚本解决了类似的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM