Sunday, December 18, 2011

Spring IOC and Dependancy Injection

In Spring, Inversion of Control(IOC) is implemented using Dependancy Injection(DI) Design Pattern. Let's understand DI with java example and then I will see how DI can solve tightly coupled problem and Spring container will inject dependency.

What is Inversion of Control?
IOC allows you to decouple your program into separate components that don't know each other. supposed if I have two classes which implements common interface then In order to use, In my Java class i need to create instance of those classes. which looks like tightly coupled.

If we can define which class to use at runtime using Injecting dependency at runtime then it will be good , right? This is where IOC comes to Picture.

Concept IoC that the Spring Framework uses is "Injection of required resources or dependency at Run-time into the dependent resource," which is also known as Dependency Injection.

There are three forms or styles of Dependency Injection.
1.Constructor Injection
2.Setter Injection
3.Interface Injection

1. Constructor Injection: Here, IoC container uses the constructor to inject the dependency. Since All dependencies are declared in one constructor, it's added advantage.
- here, handling over dependencies takes during instantiation of the dependent object.

2. Setter Injection: Here, DI uses Setters to inject the required resources or dependencies.Meaning class will have setters, the IoC container will use the setters to provide the resource at run-time.
-  here, handling over dependencies takes after the dependent object is instantiated


3. Interface Injection: here, implementations of the interface can be injected, whereas with the other two, the object of the class specified is injected. Spring does not provide direct support for Interface Injection as far as i know.

QuizMaster.java
package com.anuj.spring.core.ioc;

/**
 * @author Anuj J Patel
 *
 */
public interface QuizMaster {
 public String popQuestion();
}

SpringQuizMaster.java
package com.anuj.spring.core.ioc;
/**
 * 
 * @author Anuj J Patel
 *
 */
public class SpringQuizMaster implements QuizMaster{

 @Override
 public String popQuestion() {
  return "Are you new to Spring ?";
 }
}

StrutsQuizMaster.java
package com.anuj.spring.core.ioc;

/**
 * 
 * @author Anuj J Patel
 *
 */
public class StrutsQuizMaster implements QuizMaster{

 @Override
 public String popQuestion() {
  return "Are you new to Struts?";
 }

}

QuizMasterService.java
package com.anuj.spring.core.ioc;

/**
 * 
 * @author Anuj J Patel
 *
 */
public class QuizMasterService {
 QuizMaster quizMaster;
 //QuizMaster quizMaster = new SpringQuizMaster();  tightly coupled
 //QuizMaster quizMaster = new StrutsQuizMaster();  tightly coupled

 public void setQuizMaster(QuizMaster quizMaster) {
  this.quizMaster = quizMaster;
 }
 
 public void askQuestion(){
  System.out.println(quizMaster.popQuestion());
 }
}

If we create instance of QuizMaster using QuizMaster quizMaster = new SpringQuizMaster(); Then this architecture is lightly coupled. and requried to modify class QuizMasterService if we want to use StrutsQuizMaster. Instead of hard coding any values we will allow the container to inject the required dependancies.

Using DI, The value for the QuizMaster will be set using the setQuizMaster() method. Which quizMaster we can use? that we can specified in Spring beans.xml


beans.xml

 
    
    
    
        
            
            
        
    


QuizProgram.java
ackage com.anuj.spring.core.ioc;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 
 * @author Anuj Patel
 *
 */
public class QuizProgram {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring_core_ioc_beans.xml");
        QuizMasterService quizMasterService = (QuizMasterService) context.getBean("quizMasterService");
        quizMasterService.askQuestion();
    }
}

 Thanks to Vanilla for helping me to understand this concept. Credit goes to vanilla

No comments:

Post a Comment