On This Page
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
@Serviceor@Componentclasses each@Autowiredinto one another. - Controller ↔ Service, Service ↔ Repository cycles.
- A config class with
@Beanmethods 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
@Beanmethods referencing one another? - Review design: Could a mediator or event‐driven approach break the cycle?
- As a last resort: Apply
@Lazyor 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
UserContextinterface that only exposes methods OrderService really needs. - Have
UserServiceimplement it. - Inject the interface into
OrderServiceso 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.
GopiGorantala — Java, Spring, Kafka, Flink, Distributed systems Newsletter
Join the newsletter to receive the latest updates in your inbox.