Cyclic dependency is the one of the major limitation of the Injection process in Spring. Constructor Injection has chance of having Cyclic Dependency, while the same is not possible in case of Setter Injection.

When both the beans depends on each other for injecting the bean property then it forms the Cyclic Dependency. In Cyclic Dependency containers goes on infinite loop for getting the bean instance, so to avoid this type of situation ( Cyclic Chaining ) it finally create the instance of second bean by calling default constructor. So as a result only one bean will be injected and another remain uninjected.

To better understand the above statement lets take an example :
There are two bean A and B and both depends on each other.

Case 1: With Constructor Injection

A.java
public class A {

   B b;               // Bean property
 
   public A(B b) {
      this.b = b;    // Constructor Injection
   }
}

B.java
public class B {

   A a;               // Bean property
 
   public B(A a) {
      this.a = a;    // Constructor Injection
   }
 public static void main(String[] args) {
     ApplicationContext ctx=new ClassPathXmlApplicationContext("Spring-Core.xml");
     Hello hello = (Hello)ctx.getBean("hello");
  
 } 
}

Spring-Core.java

<?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-3.0.xsd">

<bean id="a" class="com.def.A" autowire="constructor">
</bean>

<bean id="b" class="com.def.B" autowire="constructor">
</bean>

</beans>

Explanation: 
1. Read the first bean tag in XML file and found one dependencies of bean B. 
2. Try to get the instance of bean B but not running in the Spring Container.
3. Try to create the instance by reading the bean definition of B.
4. But again found the dependency of A on B. 
5. Now Container try to get the instance of bean A ( Which already have dependency ) . 
6. Like this it will form infinite loop and at last one bean will be injected by avoiding the Cyclic chaining.   

Note: This happens all because in case of Constructor Injection
1. Container first inject the dependencies.
2. Then create the instance of the current bean. 

So in the above condition it both the bean cannot be injected and hence non of the instance will be created and hence form the Cyclic Dependency but to avoid Cyclic dependencies , container create the instance of second bean by calling the default constructor. 

Case 2: With Setter Injection

A.java
public class A {

   B b;               // Bean property
 
   public setA(B b) {
      this.b = b;    // Constructor Injection
   }
}

B.java
public class B {

   A a;               // Bean property
 
   public setB(A a) {
      this.a = a;    // Constructor Injection
   }
 public static void main(String[] args) {
     ApplicationContext ctx=new ClassPathXmlApplicationContext("Spring-Core.xml");
     Hello hello = (Hello)ctx.getBean("hello");
  
 } 
}

Spring-Core.java

<?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-3.0.xsd">

<bean id="a" class="com.def.A" autowire="byType">
</bean>

<bean id="b" class="com.def.B" autowire="byType">
</bean>

</beans>

Explanation: 

1. Read the first bean tag in XML file and found one dependencies of bean B. 

2. Container create the instance of A and try to inject the dependencies. 

2. So try to get the instance of bean B to Inject the bean property but not running in the Spring Container.
3. Then try to create the instance by reading the bean definition of B.
4. Again found the dependency of A on B and again before injecting the dependencies on B, first create the instance of B.  
5. Now Container try to inject the A's bean property because its instance is available . 
6. And finally Instance B is also available and inject the bean property of B.  

Note: This happens all because in case of Setter Injection
1. Container first create the instance of the current bean 
2. Then Inject the dependencies if any.  

So like this no chance of having any Cyclic Dependency in Setter Injection because of creating the current bean instance first, so anyhow a bean instance will be available to inject the bean properties.


0 comments:

Post a Comment

Ads 468x60px

.

Ads

.

Featured Posts

Popular Posts

Like Us On FaceBook

Total Pageviews

Online Members

Live Traffic