Table of Contents
What is a circular dependency?
The circular dependency error occurs when a bean type A is dependent on B and B is also dependent on A.
Example:
BeanA -> BeanB -> BeanA
BeanA
@Component
public class BeanA{
@Autowired
private BeanB beanB;
}
BeanB
@Component
public class BeanB{
@Autowired
private BeanA beanA;
}
How does Spring create a Bean?
Let’s take an example of the following scenario:
BeanA -> BeanB -> BeanC
In the above scenario, the spring first creates a bean of type BeanC and creates a bean of type BeanB then injects BeanC into Bean B and creates a bean type of BeanA then injects BeanB into BeanA. There is not any confusion while creating and injecting these beans.
But, let’s take an example of the following scenario:
BeanA -> BeanB -> BeanA
In this case, the spring can’t decide which dependency to create first. Because the bean of type BeanA is dependent on BeanB and BeanB is also dependent on BeanA.
This is why circular dependency occurs.
Solution
The best option is to redesign the code structure. So that we can avoid this type of issue. But still there needs to be a workaround apart from the redesign. Because there may be legacy code that might be already tested and redesigning this code may take a longer time to develop as well as test.
Hence, we can use the following solutions.
Lazily Initialize a Bean
To initialize bean lazily we can use @Lazy
annotation from org.springframework.context.annotation
package.
Example:
BeanA
@Component
public class BeanA{
@Autowired
private BeanB beanB;
}
BeanB
@Component
public class BeanB{
@Autowired
@Lazy
private BeanA beanA;
}
The main disadvantages of this approach is, we need to define @Lazy
annonation on every place where dependency is injected.
Via configuration file
Another and easiest solution is to tell Spring application to allow circular reference.
We can set following configuration to true either in application.properties
or application.yml
file.
Example:
application.properties
spring.main.allow-circular-references= true
application.yml file
spring:
main:
allow-circular-references: true
In this way, we can solve the circular dependency error in Spring.
Conclusion
In this post, we learned to solve the circular dependency error in spring by lazily initializing the beans.