🔴 The Error You're Seeing

Confirm this matches your console output. If it does, you're in the right place.

ERROR LOG*************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: ┌─────┐ | userService defined in file [/com/devinhyderabad/service/UserService.class] ↑ ↓ | userProfileService defined in file [/com/devinhyderabad/service/UserProfileService.class] └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the cycle of dependencies between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.

⚡ Quick Fix Works 80% of the time

Refactor the classes to extract shared logic into a 3rd bean, or use @Lazy.

@Service public class UserService { public UserService(@Lazy UserProfileService profileService) { ... } }

🧠 Why this Happens

Tap to expand the deep technical explanation

Bean A requires Bean B, and Bean B requires Bean A. Spring Boot 3 disabled circular references by default to promote clean architecture, causing the app to crash instead of resolving the loop.

The HITEC City Parking Spot Analogy:

Two people are trying to paint a portrait of each other. Person A won't sit still until Person B sits, and Person B won't sit until Person A sits. Nothing happens.

🔁 How to Reproduce Confirm this is your error

Create `UserService` with `@Autowired UserProfileService`. Create `UserProfileService` with `@Autowired UserService`. Run the Spring Boot 3 app.

🛠️ Solutions (5 Ways to Fix)

Solution 1✓ Most common cause

Use @Lazy annotation

👉 Use this as a quick fix when you cannot 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; } }
Solution 2

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.

@Service public class SharedLogicService { ... } @Service public class UserService { @Autowired SharedLogicService shared; // No cycle }
Solution 3

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; } }
Solution 4

Re-enable circular references (Not Recommended)

👉 Use this ONLY as a last resort when migrating a massive legacy Spring Boot 2 app to Spring Boot 3.

Spring Boot 2 allowed this by default. You can turn the old behavior back on, but it's a band-aid.

# application.properties spring.main.allow-circular-references=true
Solution 5

Use ApplicationContext to fetch bean at runtime

👉 Use this if the dependency is only needed for one specific method, not at startup.

Instead of autowiring, inject the ApplicationContext and get the bean when you need it.

@Service public class UserService { @Autowired private ApplicationContext context; public void doWork() { UserProfileService service = context.getBean(UserProfileService.class); service.doSomething(); } }

📋 Version Notes

Spring Boot 2.x

Circular references were allowed by default.

Spring Boot 3.x

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.