0
0
SpringbootDebug / FixBeginner · 4 min read

How to Fix Circular Dependency in Spring Framework

A circular dependency in Spring happens when two or more beans depend on each other directly or indirectly, causing a loop. To fix it, you can use @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.

java
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;
    }
}
Output
org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?
🔧

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.

java
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;
    }
}
Output
Application context starts successfully without circular dependency errors.
🛡️

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.

Key Takeaways

Circular dependencies happen when beans depend on each other creating a loop.
Use @Lazy to delay bean creation and break the cycle.
Switch to setter injection to allow Spring to create beans in order.
Refactor code to reduce tight coupling and one-way dependencies.
Use tools to detect circular dependencies early in development.