It is the heart of spring framework, it facilitates the idea of keeping classes independent of each other and injecting them wherever required. DI helps decouple your application objects from each other.
Spring framework provides two ways to inject dependency
1. By Constructor
2. By Setter method
1. By Constructor Injection
It is achieved when the container invokes the target constructor with the number of arguments. Below is an example where a class is injected to another via constructor by passing the reference as constructor arguments.
/********Mobile class*********/
public class Mobile {
private Recharge recharge;
public Mobile(Recharge recharge) {}
System.out.println("Inside Mobile constructor." );
this.recharge = recharge;
}
public void getRecharge() {
recharge.doRecharge();
}
}
}
/********Recharge class*********/
public class Recharge {}
public Recharge(){
System.out.println("Inside Recharge constructor." );
}
}
public void doRecharge() {
System.out.println("Inside doRecharge." );
}
}
}
/********Main class*********/
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
Mobile mb = (Mobile) context.getBean("mobile");
mb.getRecharge();
}
}
/********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-3.0.xsd">
<!-- Definition for Mobile bean -->
<bean id = "mobile" class = "com.programmertoday.Mobile">
<constructor-arg ref = "recharge"/>
</bean>
<!-- Definition for Recharge bean -->
<bean id = "recharge" class = "com.programmertoday.Recharge"></bean>
</beans>
OUTPUT:
------
Inside Recharge constructor.
Inside Mobile constructor.
Inside doRecharge.
2. By Setter Injection
It is achieved when the container invokes the setter methods on your beans after calling a no-arg constructor or no-arg static factory method to instantiate your bean.
public class TextEditor {
private SpellChecker spellChecker;
// a setter method to inject the dependency.
public void setSpellChecker(SpellChecker spellChecker) {
System.out.println("Inside setSpellChecker." );
this.spellChecker = spellChecker;
}
// a getter method to return spellChecker
public SpellChecker getSpellChecker() {
return spellChecker;
}
public void spellCheck() {
spellChecker.checkSpelling();
}
}
Difference between constructor and setter injection
| Factor | SI(Setter Injection) | CI(Constructor Injection) |
|---|---|---|
| Partial dependency | Can be injected using setter injection, e.g if there is a Bean with 4 properties having 4 args constructor and setter methods, and if you want to pass value for only one property from other class its possible by setter method only. | Not possible with constructor injection. |
| Overriding | If both the types of DI are present in a file then the SI overrides the CI. | Less priority over SI |
| Easy Changes | No need to create an instance of a class to change a value using setter injection. | But using constructor injection one has to create a new bean instance. |
Summary
In this tutorial we learnt about Spring Dependency Injection, two types of dependency injection (constructor and setter) and its difference.
Hope you liked it !