Having an issue resolving circular dependency in a Spring Boot Starter project (version 3.1) with Gradle.
Using setter injection with @Autowired
annotation.
After building the project, the following output displayed:
Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2023-07-25T19:47:02.265-04:00 ERROR 27261 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
The dependencies of some of the beans in the application context form a cycle:
┌─────┐
| classA
↑ ↓
| classB
└─────┘
Action:
Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.
*Note: Project ran successfully with an older Spring Boot version (2.5.15). Also tested it using 2.6.0 - same issue occurred.
Appears to be an issue with versions 2.6 and above.
Application code below:
MainApp.java
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MainApp {
public static void main(String[] args) {
SpringApplication.run(MainApp.class);
}
}
ClassA.java
package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class ClassA {
private ClassB classB;
@Autowired
public void setClassB(ClassB classB) {
this.classB = classB;
}
}
ClassB.java
package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class ClassB {
private ClassA classA;
@Autowired
public void setClassA(ClassA classA) {
this.classA = classA;
}
}
*Please note: I have read the 2.6 release notes.
Found that setting spring.main.allow-circular-references=true
in application.properties file is not recommended.
Also found that setter injection with @Autowired
annotation hides the cycle.
This should not occur due to being one of the resolution methods suggested in the Spring documentation.
Comment From: bclozel
Closing as a duplicate of https://github.com/spring-projects/spring-boot/issues/36286
Again, if you don't want to set that property you should avoid this pattern in the first place.
Comment From: zpreston123
@bclozel For use cases where setter injection is necessary, resolving this would help developers facing similar issues.
The following resolution methods worked in the code example above:
1. Constructor injection with @Lazy
annotation
2. @PostConstruct
annotation
As noted previously, setter injection worked using an older Spring Boot version (2.5.15).
Any assistance would be greatly appreciated.