Overview
In my previous blog we saw an overview of Spring IoC and DI.
Here we will see Dependency Injection (DI) in detail by answering following question:
- What is DI
- Ways of injecting Dependency using XML
Dependency Injection
- Dependency Injection (DI) is a design pattern that removes the dependency from the programming code so that it can be easy to manage and test the application.
- Dependency Injection makes our programming code loosely coupled.
Ways of injecting Dependency
- Construction Injection
- Setter Injection
Construction Injection using XML
- We will see through an example how we can inject dependency using Constructor
- I have a class Car where I need Paint implementation
- I will inject Paint class inside Car
Paint class
public interface Paint {
public void getColor();
}
public class RedPaint implements Paint {
public RedPaint() {
System.out.println("RedPaint Constructor called");
}
@Override
public void getColor() {
System.out.println("I will paint Red color");
}
}
Car Class
// interface
public interface Vehicle {
public void getType();
public void getPaint();
}
// Implementation
public class Car implements Vehicle{
private Paint paint;
// constructor method which will be called from XML
Car(Paint mypaint){
System.out.println("Construction injection called. Setting Paint");
paint = mypaint;
}
@Override
public void getType() {
System.out.println("This is a Car");
}
@Override
public void getPaint() {
paint.getColor();
}
}
xml configuration
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- define the beqn -->
<bean id="myPaint" class="com.main.spring.common.RedPaint"></bean>
<!-- Injection above bean in Car as Constructor -->
<bean id="myCar" class="com.main.spring.constructorInj.Car">
<constructor-arg ref="myPaint" ></constructor-arg>
</bean>
</beans>
Main Class
public class MainApp {
public static void main(String[] args) {
// load the spring configuration file
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("contInjContext.xml");
System.out.println("Loading Config Done");
Vehicle veh = context.getBean("myCar", Vehicle.class);
veh.getPaint();
veh.getType();
context.close();
}
}
OUTPUT:
Aug 05, 2018 9:24:15 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@dcf3e99: startup date [Sun Aug 05 21:24:15 IST 2018]; root of context hierarchy
Aug 05, 2018 9:24:15 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [contInjContext.xml]
RedPaint Constructor called
Construction injection called. Setting Paint
Loading Config Done
I will paint Red color
This is a Car
Aug 05, 2018 9:24:15 PM org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@dcf3e99: startup date [Sun Aug 05 21:24:15 IST 2018]; root of context hierarchy
Explanation
When we execute MainApp Spring reads xml file and prepares Paint and Car Bean for use.
<bean id="myPaint" class="com.main.spring.common.RedPaint"></bean>
In above line Spring create an Bean of RedPaint
<bean id="myCar" class="com.main.spring.constructorInj.Car">
<constructor-arg ref="myPaint" ></constructor-arg>
</bean>
In above line Spring creates Bean of Car class and passed RedPaint Bean as an Constructor in Car class.
Vehicle veh = context.getBean("myCar", Vehicle.class);
Our bean is ready for work since all work was done by Container when we call veh.getType(); we get this output I will paint Red color
Setter Injection using XML
We will use same example as above with few changes
xml file
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- define the beqn -->
<bean id="myPaint" class="com.main.spring.common.RedPaint"></bean>
<bean id="myCar" class="com.main.spring.setterInj.Car">
<!-- Spring will look for method Name "setPaint"
first letter of name as capital and matched rest to method name -->
<property name="paint" ref="myPaint"></property>
</bean>
</beans>
Car class
public class Car implements Vehicle{
private Paint paint;
// Setter method which will be called in XML
public void setPaint(Paint mypaint){
System.out.println("Setter injection called. Setting Paint");
paint = mypaint;
}
@Override
public void getType() {
System.out.println("This is a Car");
}
@Override
public void getPaint() {
paint.getColor();
}
}
Main class
public class MainApp {
public static void main(String[] args) {
// load the spring configuration file
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("setterInjContext.xml");
System.out.println("Loading Config Done for Setter Injection");
Vehicle veh = context.getBean("myCar", Vehicle.class);
veh.getPaint();
veh.getType();
context.close();
}
}
OUTPUT:
Aug 05, 2018 9:33:51 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@dcf3e99: startup date [Sun Aug 05 21:33:51 IST 2018]; root of context hierarchy
Aug 05, 2018 9:33:51 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [setterInjContext.xml]
RedPaint Constructor called
Setter injection called. Setting Paint
Loading Config Done for Setter Injection
I will paint Red color
This is a Car
Aug 05, 2018 9:33:51 PM org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@dcf3e99: startup date [Sun Aug 05 21:33:51 IST 2018]; root of context hierarchy
Explanation
Only difference when compare to Constructor injection code is in the way Objects are injected
// in xml instead of constructor-arg we have property
<bean id="myCar" class="com.main.spring.setterInj.Car">
<property name="paint" ref="myPaint"></property>
</bean>
// Setter method which will be called in XML
public void setPaint(Paint mypaint){
System.out.println("Setter injection called. Setting Paint");
paint = mypaint;
}
Summary
- We saw how to inject Bean using Constructor and Setter in XML
- You can get the code used above here. Just look for com.main.spring.setterInj and com.main.spring.constructorInj package.
0 Comments