Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Good practices on finding circular dependencies between spring beans

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.

like image 708
Simeon Avatar asked Dec 06 '11 15:12

Simeon


People also ask

How do you handle cyclic dependency between beans?

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.

How do you deal with circular dependencies?

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.

How do I find circular dependencies?

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.

Where can we face the problem of circular dependency and which approach can resolve 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.


2 Answers

Here's 2 tools that advertise dependency graph generation. I don't have any experience with them however.

  • SpringSource's build of Eclipse - It advertises a "Spring Bean Dependency Graph"
  • MyEclipse for Spring - says "bean dependency graphs"
like image 152
Gray Avatar answered Nov 02 '22 13:11

Gray


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.

like image 37
lars Avatar answered Nov 02 '22 14:11

lars