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.


Related Posts:

  • Dependencies Injection of Bean Dependencies means how a java bean is dependent on another bean class. That means if we defines any bean reference as a class member to another bean class, then it results in a bean dependent on another. A primitive type or… Read More
  • Benefit of using Spring Framework Provide a good programming practice by decoupling the layers. If you are using spring in your project it decouples the layers and hence it's easy to write the test case for them. So it's easy from maintenance point of view.… Read More
  • IoC Container In Spring IOC stands for the Inversion of Container. It is a container used in Spring core Framework. It is responsible for managing the states of the object i.e from its creation till its destruction. Before Spring framework, develo… Read More
  • Spring Implicit Wiring : byType In this type of auto-wiring container detect the bean instance with its data type and checks the data type of the bean instance running in the container with the bean type mentioned in the dependency bean. Some of the task … Read More
  • Alternatives of Open Session In View(OSIV) Today I am going to tell you other alternative you can do in order to avoid LazyInitializationException: Session has been closed. If you are using SPRING with HIBERNATE that you can take the advantages of IOC and AOP. These … Read More

0 comments:

Post a Comment

Ads 468x60px

.

Ads

.

Featured Posts

Popular Posts

Like Us On FaceBook

Total Pageviews

201978

Online Members

Live Traffic