Backend Development 10 min read

Understanding and Resolving Circular Dependencies in Spring Boot

This article explains what circular dependencies are in Spring Boot, why they cause startup failures from version 2.6 onward, and presents several practical solutions—including constructor injection, setter injection, @Lazy, @Autowired(required=false), @DependsOn, and interface segregation—accompanied by code examples.

Top Architect
Top Architect
Top Architect
Understanding and Resolving Circular Dependencies in Spring Boot

The article explains what circular dependencies are in Spring Boot applications, where two or more beans depend on each other, forming a cycle that prevents proper initialization.

Before Spring Boot 2.6 the framework automatically resolved such cycles; starting with 2.6 it detects them and throws an error, so the application fails to start.

*************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: ┌─────┐ | componentA ↑ ↓ | componentB └─────┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.

Typical causes include constructor injection cycles, property injection cycles, and method injection cycles.

Spring Boot provides several ways to break the cycle:

Constructor injection – inject dependencies through constructors instead of fields.

Setter injection – use setter methods to inject dependencies.

Lazy injection – annotate one side with @Lazy to defer its creation.

Set @Autowired(required = false) to make the injection optional.

Use @DependsOn to control bean initialization order.

Below are code examples.

ComponentA (field injection)

import org.springframework.stereotype.Service;
import javax.annotation.Resource;

@Service
public class ComponentA {
    @Resource
    private ComponentB componentB;
}

ComponentB (field injection)

import org.springframework.stereotype.Service;
import javax.annotation.Resource;

@Service
public class ComponentB {
    @Resource
    private ComponentA componentA;
}

With Spring Boot 2.6 this configuration fails with the error shown above.

Constructor‑injection solution

public class A {
    private B b;
    public A(B b) { this.b = b; }
}

public class B {
    private A a;
    public B(A a) { this.a = a; }
}

@Lazy injection example

@Component
public class A {
    private final B b;
    public A(@Lazy B b) { this.b = b; }
}

@Component
public class B {
    private final A a;
    public B(A a) { this.a = a; }
}

Interface segregation solution

public interface Service {
    void doSomething();
}

public class A {
    private final Service service;
    public A(Service service) { this.service = service; }
}

public class B {
    private final Service service;
    public B(Service service) { this.service = service; }
}

@Service
public class ServiceImpl implements Service {
    private final A a;
    private final B b;
    public ServiceImpl(A a, B b) { this.a = a; this.b = b; }
    @Override
    public void doSomething() { /* ... */ }
}

By applying any of these techniques, the circular dependency is eliminated and the Spring Boot application can start normally.

BackendJavaSpring Bootdependency injectionCircular Dependency
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.