Open In App

Spring Dependency Injection with Example

Last Updated : 04 Aug, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Dependency Injection is the main functionality provided by Spring IoC (Inversion of Control). The Spring-Core module is responsible for injecting dependencies through either Constructor or Setter methods. The design principle of Inversion of Control emphasizes keeping the Java classes independent of each other and the container frees them from object creation and maintenance. These classes, managed by Spring, must adhere to the standard definition of Java-Bean. Dependency Injection in Spring also ensures loose coupling between the classes.

Need for Dependency Injection

  • Suppose class One requires an object of class Two to perform its operations. It means class One is dependent on class Two.
  • While such dependency may seem acceptable, in real-world applications, it can lead to Tight coupling, Difficulty in maintenance, reduced testability or potential system failures.
  • Therefore, direct dependencies should be avoided.
  • Spring IoC (Inversion of Control) resolves such dependency issues using Dependency Injection (DI).
  • Dependency Injection makes the code easier to test and reuse.
  • Loose coupling between classes is achieved by defining interfaces for common functionality or Letting the injector (Spring container) provide the appropriate implementation.
  • The task of instantiating objects is done by the container according to the configurations specified by the developer.

Types of Spring Dependency Injection

There are two primary types of Spring Dependency Injection:

1. Setter Dependency Injection (SDI):

Setter DI involves injecting dependencies via setter methods. To configure SDI, the @Autowired annotation is used along with setter methods and the property is set through the <property> tag in the bean configuration file.

Java
package com.geeksforgeeks.org;

import com.geeksforgeeks.org.IGeek;
import org.springframework.beans.factory.annotation.Autowired;

public class GFG {

    // The object of the interface IGeek
    private IGeek geek;

    // Setter method for property geek with @Autowired annotation
    @Autowired
    public void setGeek(IGeek geek) {
        this.geek = geek;
    }
}

Bean Configuration:

XML
<beans 
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
          http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

    <bean id="GFG" class="com.geeksforgeeks.org.GFG">
        <property name="geek"  ref ="CsvGFG" />
    </bean>
    
<bean id="CsvGFG" class="com.geeksforgeeks.org.impl.CsvGFG" />
<bean id="JsonGFG" class="com.geeksforgeeks.org.impl.JsonGFG" />
    
</beans>

This injects the CsvGFG bean into the GFG object using the setter method (setGeek).

2. Constructor Dependency Injection (CDI):

Constructor DI involves injecting dependencies through constructors. To configure CDI, the <constructor-arg> tag is used in the bean configuration file.

Java
package com.geeksforgeeks.org;

import com.geeksforgeeks.org.IGeek;

public class GFG {

    // The object of the interface IGeek
    private IGeek geek;

    // Constructor to set the CDI
    public GFG(IGeek geek) {
        this.geek = geek;
    }
}

Bean Configuration:

XML
<beans 
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
          http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">


    <bean id="GFG" class="com.geeksforgeeks.org.GFG">
        <constructor-arg>
            <bean class="com.geeksforgeeks.org.impl.CsvGFG" />
        </constructor-arg>
    </bean>
    
<bean id="CsvGFG" class="com.geeksforgeeks.org.impl.CsvGFG" />
<bean id="JsonGFG" class="com.geeksforgeeks.org.impl.JsonGFG" />
    
</beans>

This injects the CsvGFG bean into the GFG object via the constructor.

Setter Dependency Injection (SDI) vs. Constructor Dependency Injection (CDI)

Setter DI Constructor DI
Creates immutable objects. Dependencies can't be modified after creation.Creates mutable objects. Dependencies can be modified after creation.
All dependencies must be provided at creation.Dependencies can be injected later.
Requires addition of @Autowired annotation.

@Autowired annotation is not needed.

It results in circular dependencies or partial dependencies.It too can have circular dependencies, it just fails faster and more explicitly.
Easier unit testing - can create objects directly with mock dependencies.Requires framework or manual setter calls for dependency injection in tests.

Example of Spring DI

  • We have 4 main components: IEngine interface, ToyotaEngine class (implements IEngine), Tyres class, Vehicle class (depends on IEngine and Tyres).
  • Here, Vehicle is not creating it's own dependencies, Spring is handling object creating and wiring for us.
  • Beans are defined in the XML configuration for: ToyotaEngine, Two Tyres instances (tyre1Bean, tyre2Bean), Two Vehicle instances.
  • Two types of dependency injection are used: InjectwithConstructor uses constructor injection via <constructor-arg> tags and InjectwithSetter uses setter injection via <property> tags.
  • Spring is determining which engine and tyres to inject into each Vehicle, based on the configuration.
  • Vehicle is not aware of the actual implementation of the engine or tyre.
  • This makes this system a loosely coupled system making it easier to maintain, more flexible, simpler to swap components without breaking the core logic.

Process Flow:

Process Flow

Code Implementation:

Enigne.java
interface IEngine {
    String EMISSION_NORMS = "BSIV";
    String importOrigin();
    double cost();
}
ToyotaEngine.java
public class ToyotaEngine implements IEngine {
    String company;
    double cost;
    public double getCost() { return cost; }

    public void setCost(double cost) { cost = this.cost; }

    public String getCompany() { return company; }

    public void setCompany(String company)
    {
        this.company = company;
    }

    @Override public String importOrigin()
    {
        return "Japan";
    }

    @Override public double cost() { return cost; }
    @Override public String toString()
    {
        return "This is Engine object from: " + company;
    }
}
Tyres.java
public class Tyres {

    String name;
    String place;
    String message;

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getPlace() { return place; }
    public void setPlace(String place)
    {
        this.place = place;
    }
    public String getMessage() { return message; }
    public void setMessage(String message)
    {
        this.message = message;
    }

    @Override public String toString()
    {
        return "This is Tyre object: " + name + " " + place
            + " " + message;
    }
}
Vehicle.java
public class Vehicle {

    IEngine engine;
    Tyres tyre;

    public Tyres getTyre() { return tyre; }

    public void setTyre(Tyres tyre)
    {
        System.out.println("tyre instantiated via setter");
        this.tyre = tyre;
    }

    public Vehicle(IEngine engine, Tyres tyre)
    {
        System.out.println("instantiated via constructor");
        this.engine = engine;
        this.tyre = tyre;
    }

    public Vehicle() {}
    public IEngine getEngine() { return engine; }
    public void setEngine(IEngine engine)
    {
        System.out.println("instantiated via setter");
        this.engine = engine;
    }

    @Override public String toString()
    {
        return engine + " " + tyre;
    }

    public static void main(String a[])
    {
        ApplicationContext rootctx
            = new ClassPathXmlApplicationContext(
                "springContext.xml");

        // Instantiating the obj1 via Constructor DI
        Vehicle obj1 = (Vehicle)rootctx.getBean(
            "InjectwithConstructor");

        // Instantiating the obj1 via Setter DI
        Vehicle obj2
            = (Vehicle)rootctx.getBean("InjectwithSetter");

        System.out.println(obj1);
        System.out.println(obj2);
        System.out.println(obj1 == obj2);
    }
}
pom.xml
<dependencies>
  
    <!-- https:// mvnrepository.com/artifact
    /org.springframework/spring-core -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.3.11.RELEASE</version>
    </dependency>
  
    <!-- https:// mvnrepository.com/artifact
    /org.springframework/spring-context -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.3.11.RELEASE</version>
    </dependency>
</dependencies>
springContext.xml
< bean id="tyre1Bean" class="com.techgene.Tyres">
    <property name="name" value="MRF">
    </ property>

    <property name="place" value="India">
    </ property>

    <property name="message" value="Make in India">
    </ property>

</ bean>

< bean id="ToyotaBean" class="com.techgene.ToyotaEngine">
    <property name="company" value="Toyota">
    </ property>

    <property name="cost" value="300000.00">
    </ property>

</ bean>

< bean id="tyre2Bean" class="com.techgene.Tyres">
    <property name="name" value="TVS">
    </ property>

    <property name="place" value="India">
    </ property>

    <property name="message" value="Make in India">
    </ property>

</ bean>

< bean id="InjectwithSetter" class="com.techgene.Vehicle">
    <property name="engine" ref="ToyotaBean">
    </ property>

    <property name="tyre" ref="tyre1Bean">
    </ property>

</ bean>

< bean id="InjectwithConstructor" class="com.techgene.Vehicle">
    <constructor - arg name="engine" ref="ToyotaBean">
    </ constructor - arg>

    <constructor - arg name="tyre" ref="tyre2Bean">
    </ constructor - arg>
    
</ bean>



Spring Dependency Injection with Example
Next Article
Article Tags :
Practice Tags :

Similar Reads