🔴 The Error You're Seeing
Confirm this matches your console output. If it does, you're in the right place.
2023-10-25 10:15:30.812 ERROR 12345 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'userService': Bean with name 'userService' has been injected into other beans [userProfileService] in its raw object as part of a circular reference, but was eventually wrapped. This means that said other beans do not use the final version of the bean.⚡ Quick Fix Works 80% of the time
Add @Lazy to one of the injections to break the creation cycle.
@Service
public class UserService {
public UserService(@Lazy UserProfileService profileService) { ... }
}🧠 Why this Happens
Tap to expand the deep technical explanation
A circular dependency occurs when Bean A depends on Bean B, and Bean B depends on Bean A (A -> B -> A). Spring tries to create A, sees it needs B, tries to create B, sees it needs A, and realizes A isn't finished creating yet. Spring Boot 3.2+ disables circular references by default, causing a crash.
The HITEC City Parking Spot Analogy:
It's like two people trying to paint a portrait of each other. Person A can't finish painting B until B sits still, but B can't sit still because they are trying to paint A.
🔁 How to Reproduce Confirm this is your error
Create two services that inject each other (e.g. UserService → UserProfileService → UserService) and start the app. Spring detects the circular reference and aborts with BeanCurrentlyInCreationException.
🛠️ Solutions (3 Ways to Fix)
Use @Lazy annotation
👉 Use this for a quick fix when you can't refactor the architecture immediately.
Tells Spring to inject a proxy instead of the real bean. The real bean is only created when actually used, breaking the creation cycle.
@Service
public class UserService {
private final UserProfileService userProfileService;
public UserService(@Lazy UserProfileService userProfileService) {
this.userProfileService = userProfileService;
}
}Refactor to a Third Bean
👉 Use this when you have time to write clean code.
Extract the shared logic that both A and B need into a new Bean C. Now A -> C, and B -> C. No circle.
// Create a new shared service
@Service
public class SharedLogicService { ... }
// Inject it into A and B
@Service
public class UserService {
@Autowired SharedLogicService shared;
}Use Setter Injection instead of Constructor
👉 Use this in legacy codebases where you can't use @Lazy.
Constructor injection requires beans to be fully formed before injection. Setter injection allows Spring to inject an unfinished bean, resolving the cycle.
@Service
public class UserService {
@Autowired
public void setUserProfileService(UserProfileService service) {
this.userProfileService = service;
}
}📋 Version Notes
Circular references were allowed by default.
Circular references are disabled by default. Crashes unless spring.main.allow-circular-references=true is set.
🛡️ How to Prevent This Next Time
Keep your service layer flat. If two services need the same logic, extract it into a third shared service.