Spring circular reference example

robbin picture robbin · Jul 5, 2012 · Viewed 48.1k times · Source

I have a circular reference in one of my projects at work using spring, which I am unable to fix, and fails with the following error at startup:

'org.springframework.security.authenticationManager': Requested bean is currently in creation: Is there an unresolvable circular reference?

I tried to recreate the same problem at a smaller level in a sample project (without all the details of my work project). I have however been unable to come up with a plausible scenario where spring fails with an error. Here's what I have:

public class ClassA {
    @Autowired
    ClassB classB;
}

public class ClassB {
    @Autowired
    ClassC classC;
}

@Component
public class ClassC {
    @Autowired
    ClassA classA;
}

@Configuration
public class Config {
    @Bean
    public ClassA classA() {
        return new ClassA();
    }

    @Bean
    public ClassB classB() {
        return new ClassB();
    }
}

I have a similar scenario in my project, which fails, and I was expecting spring to complain in my sample project as well. But it works fine! Can someone give me a simple example of how to break spring with the circular reference error?

Edit: I fixed the issue using javax.inject.Provider. The only other difference in the 2 projects was the annotations used were javax.inject.Inject and javax.annotation.ManagedBean in place of @Autowired and @Component.

Answer

Sanghyun Lee picture Sanghyun Lee · Nov 30, 2014

This is an old thread, so I guess you almost forgot about the issue, but I want to let you know about the mystery. I encountered the same problem, and mine didn't go away magically, so I had to resolve the problem. I'll solve your questions step by step.

1. Why you couldn't reproduce the circular reference exception?

Because Spring takes care of it. It creates beans and injects them as required.

2. Then why does your project produce the exception?

  • As @sperumal said, Spring may produce circular exception if you use constructor injection
  • According to the log, you use Spring Security in your project
  • In the Spring Security config, they do use constructor injection
  • Your beans which injects the authenticationManager had the circular reference

3. Then why has the exception gone away mystically?

The exception may or may not occur depends on the creation order of beans. I guess you made several *context.xml files or so, and load them with config something like below in web.xml

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:*-context.xml</param-value>
</context-param>

The xml files will be loaded by XmlWebApplicationContext class and the loading order of files are not guaranteed. It just loads files from the file system. The problem is here. There's no problem if the class loads the application context file first, because your beans are already created when they are used for the construction injection of Spring Security. But, if it loads the Spring Security context file first, the circular reference problem occurs, because Spring tries to use your beans in the constructor injection before they had been created.

4. How to solve the problem?

Force the loading order of the xml files. In my case, I loaded the security context xml file at the end of the application context file by using <import resource="">. The loading order can be changed depends on environments even with the same code, so I recommend setting the order to remove potential problems.