简体   繁体   English

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

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

Just to keep my sanity, I'm telling Spring to barf on circular references: 为了保持理智,我告诉Spring要在循环引用上做准备:

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

The problem is that the resulting stack trace actually does look like barf :| 问题是生成的堆栈跟踪实际上看起来像barf:|

How can I get a simple output of a circular references, similar to: 如何获得循环引用的简单输出,类似于:

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

?

If all your cycles are between registered components this may help (as far as I can recall you can't reference inner beans easily as they are not registered). 如果你的所有周期都在注册组件之间,这可能有所帮助(据我所知,你不能轻易引用内部bean,因为它们没有注册)。 You can register a custom listener on events generated by the bean parsers, to do so extend the application context and override initBeanDefinitionReader(), in that method set your custom listener on the beanDefinitionReader using setEventListener (you'll need to cast to XmlBeanDefinitionReader). 您可以在bean解析器生成的事件上注册自定义侦听器,这样做可以扩展应用程序上下文并覆盖initBeanDefinitionReader(),在该方法中使用setEventListener在beanDefinitionReader上设置自定义侦听器(您需要转换为XmlBeanDefinitionReader)。

The listener will be notified when ComponentDefinitions are registered and store them in a Map. 注册ComponentDefinitions时将通知侦听器并将其存储在Map中。 Once processing of the configuration is complete, you can then process the ComponentDefinitions to identify cycles using something similar to JDepend 's jdepend.framework.JavaPackage.. For each ComponentDefinition, iterate the getBeanDefinitions() and getBeanReferences() (and maybe getInnerBeanDefinitions()) and add create a "JavaPackage" for each definition and a dependency for each reference. 一旦配置处理完成,您就可以使用类似于JDepend的jdepend.framework.JavaPackage来处理ComponentDefinitions以识别周期。对于每个ComponentDefinition,迭代getBeanDefinitions()和getBeanReferences()(以及getInnerBeanDefinitions() )并为每个定义添加“JavaPackage”,并为每个引用添加依赖项。 After processing each reference and declaration, you can then interrogate the JavaPackage-like objects and spit out the results of any that return true for containsCycle() 在处理完每个引用和声明之后,您可以查询类似JavaPackage的对象,并为containsCycle()返回任何返回true的结果

have you tried the " Spring IDE "? 你试过“ Spring IDE ”吗? It shows a graphical depiction of your dependencies. 它显示了依赖项的图形描述 Not sure if it supports annotation based DI yet, but it should... 不确定它是否支持基于注释的DI,但它应该......

The approach I'd take is to write a script (probably in Python, though Groovy is probably also quite suitable) to do the following: 我采取的方法是编写一个脚本(可能在Python中,尽管Groovy可能也很合适)来执行以下操作:

  1. Parse the text of the bean graph dump to generate a directed graph of single dependencies of the form (A, B) indicating that B has a reference to A. Here A, B etc. are the nodes in the graph, and the (A, B) pairings are edges. 解析bean图形转储的文本以生成形式(A,B)的单个依赖关系的有向图,指示B具有对A的引用。这里A,B等是图中的节点,并且(A ,B)配对是边缘。
  2. Run a topological sort on the graph. 在图表上运行拓扑排序。 This removes nodes in several passes. 这会在多次传递中删除节点。 There are numerous implementations in numerous languages. 许多语言都有许多实现。 Pick one for your chosen scripting language, Google is your friend. 选择一种适合您选择的脚本语言,Google就是您的朋友。
  3. If there are any nodes left, they are your cycle (set of circular references). 如果剩下任何节点,它们就是你的循环(循环引用集)。

It may sound a bit complicated, but actually it's not. 听起来有点复杂,但实际上并非如此。 I've solved similar problems using Python scripts many a time. 我已经很多次使用Python脚本解决了类似的问题。

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

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