BeanCurrentlyInCreationException: Circular Dependencies in Spring
Spring Boot’s DI can backfire with the dreaded BeanCurrentlyInCreationException, signaling an unresolvable circular dependency. Learn why cycles occur, how they breach SOLID principles, and three fixes—refactor to break loops, use @Lazy injection, and static @Bean factory methods—to restore startup.

Table of Contents
What it looks like
***************************
APPLICATION FAILED TO START
***************************
Description:
Error creating bean with name 'serviceA': Requested bean is currently in creation:
Is there an unresolvable circular reference?
Action:
Consider declaring the factory method as static for relaxed binding
Or more verbosely:
org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'serviceA': Requested bean is currently in creation:
Is there an unresolvable circular reference?
You’ll often see something like:
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'serviceA': Requested bean is currently in creation:
Is there an unresolvable circular reference?
Why it happens
Spring’s default constructor‐injection model is acyclic. If A depends on B, and B depends on A (directly or via a chain), Spring can’t determine which to instantiate first, so it blows up.
Common culprits:
- Two
@Service
or@Component
classes each@Autowired
into one another. - Controller ↔ Service, Service ↔ Repository cycles.
- A config class with
@Bean
methods that call each other in a loop.
How to fix it
Refactor to eliminate the cycle (best practice)
Circular dependencies often violate the Single Responsibility Principle or the Dependency Inversion Principle. Ask:
- Can I introduce a third abstraction or mediator to break the loop?
- Should one service publish an event rather than call back directly?
- Could one side depend on an interface rather than a concrete class?
public interface NotificationSender {
void send(Notification n);
}
@Service
@RequiredArgsConstructor
class EmailSender implements NotificationSender {
// ...
}
@Service
@RequiredArgsConstructor
class OrderService {
private final NotificationSender sender;
// no direct dependency on EmailSender
}
Use setter (or field) injection with @Lazy
If a true cycle is unavoidable, you can defer one dependency until runtime:
@Service
public class ServiceA {
private final ServiceB serviceB;
public ServiceA(@Lazy ServiceB serviceB) {
this.serviceB = serviceB;
}
}
@Service
public class ServiceB {
private ServiceA serviceA;
@Autowired
public void setServiceA(@Lazy ServiceA serviceA) {
this.serviceA = serviceA;
}
}
This tells Spring: “Don’t try to create this dependency until the context is fully initialized.”
Tip: Prefer constructor‐injection for immutability; only fall back to setter‐injection when you need @Lazy
.
Static @Bean
factory methods
If your cycle is within a @Configuration
class:
@Configuration
public class AppConfig {
@Bean
public static A a(B b) { // note `static`
return new A(b);
}
@Bean
public static B b(A a) {
return new B(a);
}
}
Declaring factory methods static
relaxes ordering constraints, since Spring can call them without instantiating the configuration class.
Diagnostic checklist
- Spot the cycle: Trace the dependency chain in your stack‐trace.
- Search for mutual
@Autowired
: Do any two beans inject each other? - Check config classes: Are any
@Bean
methods referencing one another? - Review design: Could a mediator or event‐driven approach break the cycle?
- As a last resort: Apply
@Lazy
or static beans to defer instantiation.
Example
// BAD: circular dependency
@Service
public class UserService {
private final OrderService orderService;
public UserService(OrderService orderService) {
this.orderService = orderService;
}
}
@Service
public class OrderService {
private final UserService userService;
public OrderService(UserService userService) {
this.userService = userService;
}
}
Fix by refactoring:
- Extract a
UserContext
interface that only exposes methods OrderService really needs. - Have
UserService
implement it. - Inject the interface into
OrderService
so there’s no two‐way loop.
public interface UserContext {
User getCurrentUser();
}
@Service
@RequiredArgsConstructor
public class UserService implements UserContext {
public User getCurrentUser() { /* … */ }
// other user-related logic
}
@Service
@RequiredArgsConstructor
public class OrderService {
private final UserContext userContext;
// now no direct dependency on UserService
}
By breaking the cycle, you restore a clean, maintainable architecture that adheres to SOLID principles—and Spring will start up without a hitch.
Gopi Gorantala Newsletter
Join the newsletter to receive the latest updates in your inbox.