Spring DI

  • DI in Spring is done by 
    • Setter injection
      • Dependencies are configured using property method.
      • If we define a property tag for injecting dependency then there should be a setter method configured for the property.
      • We can create as many objects as we want using beans of same class but using different id's.
        • We can inject different values in these beans then.
      • Student Class below is an example
    • Constructor injection
      • This requires a constructor to inject dependencies instead of setter and getter methods.
      • "constructor-arg" tag is used to define the dependencies and inject them.
      • "name" property in the constructor tag is the property passed to the constructor in the class.  
      • Employee class below is an example
  • There are 3 types of dependencies
    • Dependencies in form of literals.
    • Dependencies for class type literals are called as Dependencies in form of objectives.
    • Dependencies in form of collection for classes that extend collections interface.
Student.java
 package com.springimplant.entities;  
 public class Student {  
      private int id;  
      private String studentName;  
      public int getId() {  
           return id;  
      }  
      public void setId(int id) {  
           this.id = id;  
      }  
      public String getStudentName() {  
           return studentName;  
      }  
      public void setStudentName(String studentName) {  
           this.studentName = studentName;  
      }  
      @Override  
      public String toString() {  
           return "Student [id=" + id + ", studentName=" + studentName + "]";  
      }  
 }  
Employee.java
 package com.springimplant.entities;  
 public class Employee {  
      private int id;  
      private String name;  
      public Employee(int id, String name) {  
           super();  
           this.id = id;  
           this.name = name;  
      }  
      public Employee(int id)  
      {  
           super();  
           this.id=id;  
      }  
      @Override  
      public String toString() {  
           return "Employee [id=" + id + ", name=" + name + "]";  
      }  
 }  
beans.xml
 <?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.xsd">  
      <bean id="airtel" class="com.springimplant.entities.Airtel"></bean>  
      <bean id="voda" class="com.springimplant.entities.Vodafone"></bean>  
      <bean id="sim" class="com.springimplant.entities.Jio"></bean>  
      <!-- Setter Injection -->  
      <bean id="student" class="com.springimplant.entities.Student">  
           <property name="studentName" value="Gaurav Matta"/>  
           <property name="id" value="1"></property>  
      </bean>  
      <bean id="raghavi" class="com.springimplant.entities.Student">  
           <property name="studentName" value="Raghavi Matta"/>  
           <property name="id" value="2"/>  
      </bean>  
      <!-- Constructor Injection -->  
      <bean id="employee" class="com.springimplant.entities.Employee">  
           <constructor-arg name="name" value="Raghavi" type="java.lang.String"/>  
           <constructor-arg name="id" value="1"/>  
      </bean>  
      <bean id="billy" class="com.springimplant.entities.Employee">  
           <constructor-arg name="id" value="2" type="int"/>  
      </bean>  
 </beans>  

Injecting Objects
  • Helps in loose coupling as objects are not initialized within a class.
  • We specify a Bean tag inside the property tag which defines the object of the property.
  • When we want to share a resource among multiple classes instead of injecting a separate dependency(bean) of some object every-time we can create a common bean which can be injected in multiple classes.
  • Bean cheatId is shared by "stu" and "pupil".
 <?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.xsd">  
 <bean id="cheatId" class="com.springimplant.entities.Cheating"/>  
 <bean id="stu" class="com.springimplant.entities.Student">  
           <property name="studentName" value="Gaurav Matta"/>  
           <property name="id" value="1001"/>  
           <property name="cheat" ref="cheatId"/>  
 </bean>  
 <bean id="pupil1" class="com.springimplant.entities.Pupil">  
      <property name="cheat">  
           <bean class="com.springimplant.entities.Cheating"></bean>  
      </property>  
 </bean>  
 <bean id="pupil" class="com.springimplant.entities.Pupil">  
           <property name="cheat" ref="cheatId"/>  
 </bean>  
 </beans>  
Loose Coupling using Dependency Injection
  • We use interfaces to implement Loose Coupling using Dependency Injection.
  • In our ApplicationContext we provide the property of type of Interface and at run-time we can inject the property with the type of class that implements the interface.
  • Here entities MathCheat and ScienceCheat reference to the Cheat Interface
 <?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.xsd">  
 <bean id="cheatObjectValue" class="com.springimplant.entities.Cheating"/>  
 <bean id="mathCheat" class="com.springimplant.entities.MathsCheat"/>  
 <bean id="scienceCheat" class="com.springimplant.entities.ScienceCheat"/>  
 <bean id="stu" class="com.springimplant.entities.Student">  
      <property name="cheat" ref="cheatObjectValue"/>  
      <property name="studentName" value="Gaurav Matta"/>  
      <property name="id" value="1"></property>  
      <property name="cheatingInterface" ref="mathCheat"></property>  
 </bean>  
 </beans>  

Spring Boot Dependency Injection
  • In Spring Boot dependencies are injected via application context.
  • The "SpringApplication.run()" method in Spring Boot main class  returns the application context as shown below.
  •  package com.springimplant.SpringHelloWorld;  
     import org.springframework.boot.SpringApplication;  
     import org.springframework.boot.autoconfigure.SpringBootApplication;  
     import org.springframework.context.ApplicationContext;  
     @SpringBootApplication  
     public class SpringHelloWorldApplication {  
          public static void main(String[] args) {  
               ApplicationContext applicationContext=SpringApplication.run(SpringHelloWorldApplication.class, args);  
               System.out.println("Dependency Injection Demo");  
               AnimalSpeak as=applicationContext.getBean(AnimalSpeak.class);  
               Animal animal=applicationContext.getBean(Animal.class);  
               as.setAnimal(animal);  
               as.makeAnimalSpeak();  
          }  
     }  
    
  • If we want any class to be initialized via application context we annotate with @component
    • This class now acts as  Bean which can be injected via application context.
  • We can Inject these classes from Application Context as shown above.
  • If we have 2 Bean classes of same interface type and we initialize interface from the application context then we must define @Primary annotation on one of these classes which marks the classes to be initialized by default for the compiler else the compiler will throw an error to mark one beans as @Primary as it gets confused which one to initialize.
  •  package com.springimplant.SpringHelloWorld;  
     public interface Animal {  
     public void speak();  
     }  
    
  • ssss

No comments:

Post a Comment

Spring Boot

What is circular/cyclic dependency in spring boot? When two services are interdependent on each other, that is to start one service, we requ...