简体   繁体   中英

Getting human-readable output of Spring circular references

Just to keep my sanity, I'm telling Spring to barf on circular references:

    _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 :|

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). 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).

The listener will be notified when ComponentDefinitions are registered and store them in a 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. 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()

have you tried the " Spring IDE "? It shows a graphical depiction of your dependencies. Not sure if it supports annotation based DI yet, but it should...

The approach I'd take is to write a script (probably in Python, though Groovy is probably also quite suitable) to do the following:

  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.
  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.
  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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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