Handle Circular Dependencies in Spring


In this short article, we will discuss how to handle circular dependencies in spring based applications.
If you use predominantly constructor injection, it is possible to create an unresolvable circular dependency scenario.

For example: Class A requires an instance of class B through constructor injection, and class B requires an instance of class A through constructor injection. If you configure beans for classes A and B to be injected into each other, the Spring IoC container detects this circular reference at runtime, and throws a BeanCurrentlyInCreationException.
As you see in the above diagram the two beans try to inject each other via a constructor leads to unresolvable circular dependency scenario.
Now, how to handle circular dependencies in Spring?. There are different ways to deal with this problem.

Use Setter-based Injection

One possible solution is to edit the source code of some classes to be configured by setters rather than constructors. Alternatively, avoid constructor injection and use setter injection only. In other words, although it is not recommended, you can configure circular dependencies with setter injection.
Read more about setter-based injection at Spring Dependency Injection via Setter Example

Use @Lazy Annotation

A simple way to break the cycle is saying Spring to initialize one of the beans lazily. That is: instead of fully initializing the bean, it will create a proxy to inject it into the other bean. The injected bean will only be fully created when it’s first needed.
Here is a sample code to demonstrate usage of @Lazy annotation to deal with circular dependency problem :

public  class A {
    public A(@Lazy B b){
       ....
    }
}
public  class B {
    public B(A b){
       ....
    }
}
Read more about @Lazy annotation at Spring - @Lazy Annotation Example

Use @PostConstruct Annotation

Another way to break the cycle is injecting a dependency using @Autowired on one of the beans, and then use a method annotated with @PostConstruct to set the other dependency.
Read more about @PostConstruct annotation at Spring 5 @PostConstruct and @PreDestroy Example
You can refer below links to know more about how to handle circular dependency scenario:

Related Spring Dependency Injection Posts

1. Guide to Dependency Injection in Spring
This guide provides what is dependency injection in Spring framework and what are different types of dependency injection supports in Spring with examples (constructor and setter method).

2. Spring Dependency Injection via Setter Example
In this article, we will learn how to use setter-based dependency injection in Spring Applications.

3. Spring Dependency Injection via Constructor Example
In this article, we will learn how to use constructor-based dependency injection in Spring Applications.

4. Spring - @DependsOn Annotation Example
In this article, we will discuss how to use @DependsOn annotation in Spring Applications with an example. The @DependsOn annotation can force Spring IoC container to initialize one or more beans before the bean which is annotated by @DependsOn annotation.

Comments