In this tutorial, we will discuss circular dependency in Spring. First, let's understand what a circular dependency is and how to fix it.
What is Circular Dependency in Spring ?
In Spring, a circular dependency occurs when two or more beans depend on each other.
For example, if Class A requires an instance of Class B, and Class B also requires an instance of Class A through any type of dependency injection, a circular dependency is created. In such cases, the Spring IoC container detects the circular reference at runtime and throws a BeanCurrentlyInCreationException.
In Spring Boot, circular dependencies commonly occur when using constructor injection, as shown in the following example:
import org.springframework.stereotype.Component; @Component public class BeanA { private final BeanB beanB; public BeanA(BeanB beanB) { this.beanB= beanB; } }
import org.springframework.stereotype.Component; @Component public class BeanB { private final BeanA beanA; public BeanB(BeanA beanA) { this.beanA = beanA; } }
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DemoSpringBootApplication{ public static void main(String[] args) { SpringApplication.run(HMSApplication.class); } }
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'beanA': Requested bean is currently in creation: Is there an unresolvable circular reference?
In such cases, avoid constructor injection and use setter injection to break the circular dependency.
import org.springframework.stereotype.Component; @Component public class BeanA { private final BeanB beanB; @Autowired public void setBeanB(BeanB beanB) { this.beanB= beanB; } }
import org.springframework.stereotype.Component; @Component public class BeanB { private final BeanA beanA;
@Autowired public void setBeanA(BeanA beanA) { this.beanA= beanA; } }
@Lazy. A bean marked with @Lazy is initialized only when it is first requested, rather than during application startup. This helps break the circular dependency by delaying the creation of one of the beans.In the previous example, you can apply the @Lazy annotation to the BeanB dependency in the setter method of the BeanA class.
import org.springframework.stereotype.Component; @Component public class BeanA { private final BeanB beanB; @Autowired @Lazy public void setBeanB(BeanB beanB) { this.beanB= beanB; } }
No comments:
Post a Comment