As others have said, Dependency Injection(DI) removes the responsibility of direct creation, and management of the lifespan, of other object instances upon which our class of interest (consumer class) is dependent. These instances are instead passed to our consumer class, typically as constructor parameters or via property setters (the management of the dependency object instancing and passing to the consumer class is usually performed by an Inversion of Control (IoC) container, but that’s another topic).

Any application is composed of many objects that collaborate with each other to perform some useful stuff. Traditionally each object is responsible for obtaining its own references to the dependent objects (dependencies) it collaborate with. This leads to highly coupled classes and hard-to-test code.

For example, consider a Car object.

A Car depends on wheels, engine, fuel, battery, etc. to run. Traditionally we define the brand of such dependent objects along with the definition of the Car object.

Without Dependency Injection (DI):

class Car{
  private Wheel wh= new NepaliRubberWheel();
  private Battery bt= new ExcideBattery();

  //The rest
}

Here, the Car object is responsible for creating the dependent objects.

What if we want to change the type of its dependent object – say Wheel – after the initial NepaliRubberWheel() punctures? We need to recreate the Car object with its new dependency say ChineseRubberWheel(), but only the Car manufacturer can do that.

Then what does the Dependency Injection do us for…?

When using dependency injection, objects are given their dependencies at run time rather than compile time (car manufacturing time). So that we can now change the Wheel whenever we want. Here, the dependency (wheel) can be injected into Car at run time.

After using dependency injection:

class Car{
  private Wheel wh= [Inject an Instance of Wheel at runtime]
  private Battery bt= [Inject an Instance of Battery at runtime]
  Car(Wheel wh,Battery bt) {
      this.wh = wh;
      this.bt = bt;
  }
  //Or we can have setters
  void setWheel(Wheel wh) {
      this.wh = wh;
  }
}

BeanFactory

The BeanFactory is the actual container which instantiates, configures, and manages a number of beans. These beans typically collaborate with one another, and thus have dependencies between themselves. These dependencies are reflected in the configuration data used by the BeanFactory (although some dependencies may not be visible as configuration data, but rather be a function of programmatic interactions between beans at runtime).

ApplicationContext

While the beans package provides basic functionality for managing and manipulating beans, often in a programmatic way, the context package adds ApplicationContext, which enhances BeanFactory functionality in a more framework-oriented style. Many users will use ApplicationContext in a completely declarative fashion, not even having to create it manually, but instead relying on support classes such as ContextLoader to automatically start an ApplicationContext as part of the normal startup process of a Java EE web-app. Of course, it is still possible to programmatically create an ApplicationContext.

The basis for the context package is the ApplicationContext interface, located in the org.springframework.context package. Deriving from the BeanFactory interface, it provides all the functionality of BeanFactory. To allow working in a more framework-oriented fashion, using layering and hierarchical contexts, the context package also provides the following:

  1. MessageSource, providing access to messages in, i18n-style
  2. Access to resources, such as URLs and files
  3. Event propagation to beans implementing the ApplicationListener interface
  4. Loading of multiple (hierarchical) contexts, allowing each to be focused on one particular layer, for example the web layer of an application

As the ApplicationContext includes all functionality of the BeanFactory, it is generally recommended that it be used over the BeanFactory, except for a few limited situations such as perhaps in an applet, where memory consumption might be critical, and a few extra kilobytes might make a difference. The following sections described functionality which ApplicationContext adds to basic BeanFactory capabilities.

spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <bean id="triangleId" class="com.mugil.shapes.Triangle"/>
</beans>

Triangle.java

package com.mugil.shapes;

public class Triangle {
	private String type;
	
	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public void drawShape()
	{
		System.out.println("Shape of Triangle");
	}
}

Reading value of Bean by Application Context and Bean Factory

public class Shape 
{
   public static void main(String[] args) 
   {
	ApplicationContext objContext = new ClassPathXmlApplicationContext("spring1.xml");
	Triangle objTriangle1 =  (Triangle)objContext.getBean("triangleId");
	objTriangle1.drawShape();
		
		
	BeanFactory  objBeanFactory = new XmlBeanFactory(new FileSystemResource("spring.xml"));
	Triangle objTriangle2 =  (Triangle)objBeanFactory.getBean("triangleId");
	objTriangle2.drawShape();
    }
}

Constructor Initialization
Triangle.java

package com.mugil.shapes;

public class Triangle 
{
	private String type;

        public Triangle(String ptype)
	{
		this.type = ptype;
	}
	
        public void drawShape()
	{
		System.out.println("Shape of Triangle");
	}
}

The Index Specifies which variable in the Bean is Initialized

<beans>
	<bean id="triangleId" class="com.mugil.shapes.Triangle">
		<constructor-arg index="0" value="Isolseles"/>
	</bean>
</beans>

Real World Dependency Injection
spring.xml

 
<beans>
	<bean id="triangleId" class="com.mugil.shapes.Triangle">
		<property name="pointA" ref="point1"/>
		<property name="pointB" ref="point2"/>
		<property name="pointC" ref="point3"/>
	</bean>
	
	<bean id="point1" class="com.mugil.shapes.Point">
		<property name="x" value="-20"/>
		<property name="y" value="0"/>
	</bean>
	<bean id="point2" class="com.mugil.shapes.Point">
		<property name="x" value="0"/>
		<property name="y" value="0"/>
	</bean>
	<bean id="point3" class="com.mugil.shapes.Point">
		<property name="x" value="20"/>
		<property name="y" value="0"/>
	</bean>
	
</beans>

Triangle.java

 
public class Triangle {
	private String type;
	private Point pointA;
	private Point pointB;
	private Point pointC;
	
	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public void drawShape()
	{
		System.out.println("Shape of Triangle");
	}

	public Point getPointA() {
		return pointA;
	}

	public void setPointA(Point pointA) {
		this.pointA = pointA;
	}

	public Point getPointB() {
		return pointB;
	}

	public void setPointB(Point pointB) {
		this.pointB = pointB;
	}

	public Point getPointC() {
		return pointC;
	}

	public void setPointC(Point pointC) {
		this.pointC = pointC;
	}
}

Point.java

 
package com.mugil.shapes;

public class Point {
	private int x;
	private int y;
	
	public int getX() {
		return x;
	}
	public void setX(int x) {
		this.x = x;
	}
	public int getY() {
		return y;
	}
	public void setY(int y) {
		this.y = y;
	}
}

Shape.java

 
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;

public class Shape 
{
    public static void main(String[] args) 
    {		
	BeanFactory  objBeanFactory = new XmlBeanFactory(new FileSystemResource("spring.xml"));
	Triangle objTriangle2 =  (Triangle)objBeanFactory.getBean("triangleId");
		
	System.out.println("The Refereeed Points are = ");
	System.out.println("Point A :" + objTriangle2.getPointA().getX() +" " + objTriangle2.getPointA().getY());
	System.out.println("Point B :" + objTriangle2.getPointB().getX() +" " + objTriangle2.getPointB().getY());
	System.out.println("Point C :" + objTriangle2.getPointC().getX() +" " + objTriangle2.getPointC().getY());		
	}
}

Incase the value of the bean wont be referred else where you can define the bean property simple as below

<beans>
	<bean id="triangleId" class="com.mugil.shapes.Triangle">
		<property name="pointA">
			<bean id="point1" class="com.mugil.shapes.Point">
				<property name="x" value="-20"/>
				<property name="y" value="0"/>
			</bean>			
		</property>
		<property name="pointB" ref="point2"/>
		<property name="pointC" ref="point3"/>
	</bean>

instead of

<beans>
	<bean id="triangleId" class="com.mugil.shapes.Triangle">
		<property name="pointA" ref="point1"/>
		<property name="pointB" ref="point2"/>
		<property name="pointC" ref="point3"/>
	</bean>
	
	<bean id="point1" class="com.mugil.shapes.Point">
		<property name="x" value="-20"/>
		<property name="y" value="0"/>
	</bean>
.
.
.

Using Alias

<bean id="triangleId" class="com.mugil.shapes.Triangle" name="triangleName">
.
.
.
</bean>
<alias name="triangleId" alias="triangle-alias"/>

In Java we can refer either by name or by alias as below
Using Alias

.
.
Triangle objTriangle2 =  (Triangle)objBeanFactory.getBean("triangleName");
(or)
Triangle objTriangle2 =  (Triangle)objBeanFactory.getBean("triangle-alias");
.
.

Using List
Triangle.java

public class Triangle 
{
    private List<Point> points;	
	
    public List<Point> getPoints() 
    {
	return points;
    }

    public void setPoints(List<Point> points) 
    {
 	this.points = points;
    }			
}

spring.xml

<beans>
	<bean id="triangleId" class="com.mugil.shapes.Triangle" name="triangleName">
		<property name="points">
			<list>
				<ref bean="point1"/>
				<ref bean="point2"/>
				<ref bean="point3"/>
			</list>		
		</property>		
	</bean>
	<bean id="point1" class="com.mugil.shapes.Point">
			<property name="x" value="-20"/>
			<property name="y" value="0"/>
	</bean>
	<bean id="point2" class="com.mugil.shapes.Point">
		<property name="x" value="0"/>
		<property name="y" value="0"/>
	</bean>
	<bean id="point3" class="com.mugil.shapes.Point">
		<property name="x" value="20"/>
		<property name="y" value="0"/>
	</bean>
</beans>

Shape.java

List<Point> arrPoints = objTriangle2.getPoints();
		
 for (Point objPoint : arrPoints) 
 {
   System.out.println("Point :" + objPoint.getX() +" " + objPoint.getY());
 }

Autowiring
Autowiring can be done based on name as below, byType and byConstructor.

<bean id="triangleId" class="com.mugil.shapes.Triangle" name="triangleName" autowire="byName">	
</bean>
<bean id="pointA" class="com.mugil.shapes.Point">
  <property name="x" value="-20"/>
  <property name="y" value="0"/>
</bean>
<bean id="pointB" class="com.mugil.shapes.Point">
  <property name="x" value="0"/>
  <property name="y" value="0"/>
</bean>
<bean id="pointC" class="com.mugil.shapes.Point">
  <property name="x" value="20"/>
  <property name="y" value="0"/>
</bean>

The Name of the instanceVariable in class should match the autowired xml bean Name.
Triangle.java

 
public class Triangle {	
	private Point pointA;
	private Point pointB;
	private Point pointC;
.        
.
}