Understanding Circular Dependency Issues in Spring IoC and Their Resolution

This article provides a comprehensive overview of Spring IoC circular dependency problems, explains the three types of circular dependencies, demonstrates them with Java and XML code, and details how Spring resolves singleton setter‑based cycles using its three‑level cache mechanism.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Understanding Circular Dependency Issues in Spring IoC and Their Resolution

The article presents a comprehensive overview of circular dependency problems in Spring's IoC container, explaining what they are, showing diagrams, and providing concrete code examples.

What is a circular dependency? It occurs when class A depends on class B, class B depends on class C, and class C depends back on class A, forming a closed loop.

Below is a demonstration of such a loop using two Java classes with mutual references:

public class ClassA {
    private ClassB classB;
    public ClassB getClassB() { return classB; }
    public void setClassB(ClassB classB) { this.classB = classB; }
}

public class ClassB {
    private ClassA classA;
    public ClassA getClassA() { return classA; }
    public void setClassA(ClassA classA) { this.classA = classA; }
}

The corresponding Spring XML configuration that wires the two beans:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="classA" class="ioc.cd.ClassA">
        <property name="classB" ref="classB"/>
    </bean>
    <bean id="classB" class="ioc.cd.ClassB">
        <property name="classA" ref="classA"/>
    </bean>
</beans>

A JUnit test that triggers the circular dependency:

@Test
public void test() throws Exception {
    // Create IoC container and initialize
    String resource = "spring/spring-ioc-circular-dependency.xml";
    ApplicationContext context = new ClassPathXmlApplicationContext(resource);
    // Retrieve ClassA instance – circular dependency occurs here
    ClassA classA = (ClassA) context.getBean(ClassA.class);
}

Spring can encounter three kinds of circular dependencies:

Constructor‑based injection cycles.

Setter‑based injection cycles in prototype (multi‑instance) scope.

Setter‑based injection cycles in singleton scope.

Only the third case (setter injection in singleton scope) is automatically resolved by Spring; the other two result in exceptions.

Spring resolves the singleton setter‑based cycle by using three internal caches:

First‑level cache (singletonObjects) stores fully created singleton bean instances and is exposed to application code.

Second‑level cache (earlySingletonObjects) holds early references to beans that are still being created, used internally by the container.

Third‑level cache (singletonFactories) contains ObjectFactory objects that can create early bean references on demand, which is the key mechanism for breaking the cycle.

The container checks these caches in order (first → second → third) when a bean is requested, allowing it to expose a partially constructed bean early and later replace it with the fully initialized instance.

Understanding these caches, when they are populated, and how they interact is essential for diagnosing and solving circular dependency issues in Spring.

In summary, to master Spring’s circular‑dependency handling you need to know:

The role of each of the three caches.

Why ObjectFactory is used in the third cache.

When the second cache is required.

How and when beans are added to or retrieved from each cache.

What actually gets stored in the first cache when a bean is proxied.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaBackend DevelopmentIoCspringdependency-injectioncircular-dependency
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

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.