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.

 


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.