I have this exception:
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.
Can anyone suggest good strategies for finding where the circular dependency comes from ?
I am currently looking through the context definition, but as you might imagine in a project of some maturity this takes quite a while.
So I'm generally looking for ideas on quickly finding circular bean dependencies.
A simple way to break the cycle is by telling Spring to initialize one of the beans lazily. So, instead of fully initializing the bean, it will create a proxy to inject it into the other bean. The injected bean will only be fully created when it's first needed.
There are a couple of options to get rid of circular dependencies. For a longer chain, A -> B -> C -> D -> A , if one of the references is removed (for instance, the D -> A reference), the cyclic reference pattern is broken, as well. For simpler patterns, such as A -> B -> A , refactoring may be necessary.
By running a cli command npx madge --circular --extensions ts ./ we can quickly get a list of circular dependencies of all . ts files in current directory and its subdirectories. That's it! Now you see where you have circular dependencies and can go and fix it.
Circular dependency problem can be overcome by using interfaces or events. So for the above problem, we can introduce an interface in between the “ MiddleTier ” and “ Dal ”. This interface project you will implement in the middle layer project on the “ Customer ” class.
Here's 2 tools that advertise dependency graph generation. I don't have any experience with them however.
One approach that worked for me was to write a helper class with a main method that instantiates a refreshable application context, disallows circular dependencies and calls refresh. Make sure that your beans / app context config files are on the classpath.
public class ContextChecker {
public static void main( String[] args ) {
AbstractRefreshableApplicationContext ctx =
new ClassPathXmlApplicationContext( "classpath*:/beans.xml" );
ctx.setAllowCircularReferences( false );
ctx.refresh();
}
}
This class can be run as a Java application, e.g. from inside your IDE. If circular dependencies are detected in your context, the error messages will provide information about the offending beans.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With