How Does Spring Detect and Resolve Circular Bean Dependencies?

This article explains what circular dependencies are in Spring, how the framework detects them using a three‑level cache during bean creation, and walks through a step‑by‑step example of resolving a setter‑injected circular reference between two beans.

Java Captain
Java Captain
Java Captain
How Does Spring Detect and Resolve Circular Bean Dependencies?

What is a circular dependency in Spring?

Circular dependency occurs when two or more beans depend on each other, forming a closed loop, e.g., Bean A depends on Bean B and Bean B depends on Bean A, which can prevent the application from starting.

How does Spring discover circular dependencies?

Spring uses a dependency graph to detect circular dependencies. The process includes:

1. Bean creation process

During container startup, Spring scans configuration files or annotations and attempts to create bean instances. The creation steps are:

Instantiation: create bean instance.

Property population: inject dependencies.

Initialization: run custom init methods.

2. Dependency injection process

During property population, Spring injects the bean's dependencies and tracks beans currently being created to detect cycles.

3. Circular dependency detection mechanism

Spring uses DefaultSingletonBeanRegistry to track singleton bean creation status, maintaining three caches:

singletonObjects: first‑level cache for fully initialized beans.

earlySingletonObjects: second‑level cache for early‑exposed singleton beans to resolve circular dependencies.

singletonFactories: third‑level cache storing factories for creating bean instances.

Specific detection steps

Instantiation phase

When Spring starts instantiating a bean, it marks the bean as "currently in creation" by adding its name to the singletonCurrentlyInCreation set.

Property population phase

Spring injects the bean's dependencies and checks whether each dependent bean is already in creation.

If the dependent bean is already being created, Spring detects a circular dependency and handles it based on the injection type.

Constructor injection leads to BeanCurrentlyInCreationException because the cycle cannot be resolved.

Setter injection allows Spring to retrieve the dependent bean from earlySingletonObjects or singletonFactories, exposing a partially created bean to break the cycle.

Example

Consider Bean A and Bean B with circular dependency.

Spring's dependency injection steps:

1. Instantiate Bean A

Mark Bean A as currently in creation and add to singletonCurrentlyInCreation.

Instantiate Bean A and place its factory in the third‑level cache singletonFactories.

2. Populate Bean A's properties

Detect that Bean A depends on Bean B, start creating Bean B.

Mark Bean B as currently in creation and add to singletonCurrentlyInCreation.

Instantiate Bean B and place its factory in singletonFactories.

3. Populate Bean B's properties

Detect Bean B depends on Bean A, which is already in creation, thus a circular dependency is found.

Because injection is via setter, Spring obtains a partially created Bean A from singletonFactories, exposes it in earlySingletonObjects.

Use this partial Bean A to populate Bean B's properties.

4. Complete Bean B creation

After all properties of Bean B are populated, move its instance from singletonFactories to singletonObjects (fully initialized).

5. Return to Bean A creation

Continue populating Bean A's properties; now the full Bean B instance is available from singletonObjects.

Finish Bean A creation and move it from singletonFactories to singletonObjects.

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.

Backend DevelopmentspringDependency InjectionCircular DependencyBean Lifecycle
Java Captain
Written by

Java Captain

Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.

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.