How to Fix Circular Dependency in Spring Framework
@Lazy annotation to delay bean creation, refactor your code to remove the cycle, or inject dependencies via setter methods instead of constructors.Why This Happens
Circular dependency occurs when two or more Spring beans depend on each other in a way that creates a loop. For example, Bean A needs Bean B to be created, and Bean B needs Bean A at the same time. Spring cannot create either bean because each waits for the other, causing a startup failure.
import org.springframework.stereotype.Component; import org.springframework.beans.factory.annotation.Autowired; @Component public class BeanA { private final BeanB beanB; @Autowired public BeanA(BeanB beanB) { this.beanB = beanB; } } @Component public class BeanB { private final BeanA beanA; @Autowired public BeanB(BeanA beanA) { this.beanA = beanA; } }
The Fix
You can fix circular dependencies by using the @Lazy annotation on one of the beans to delay its creation until it is needed. Alternatively, switch from constructor injection to setter injection for one bean, so Spring can create one bean first and then inject the other later. Refactoring your design to remove the circular reference is the best long-term solution.
import org.springframework.stereotype.Component; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; @Component public class BeanA { private final BeanB beanB; @Autowired public BeanA(@Lazy BeanB beanB) { this.beanB = beanB; } } @Component public class BeanB { private BeanA beanA; @Autowired public void setBeanA(BeanA beanA) { this.beanA = beanA; } }
Prevention
To avoid circular dependencies in the future, design your beans with clear, one-way dependencies. Use interfaces and separate responsibilities to reduce tight coupling. Prefer constructor injection for mandatory dependencies and setter injection for optional ones. Use tools like Spring's dependency graph visualization or static code analysis to detect cycles early.
Related Errors
Other common errors related to circular dependencies include BeanCurrentlyInCreationException and StackOverflowError caused by infinite loops in bean initialization. These can often be fixed by similar strategies: using @Lazy, refactoring code, or changing injection types.