What is Spring Dependency Injection?
Spring framework serves as a dependency injection, which is a form of inversion control ( Inversion of Control is a programming principle that inverts the flow of control as compared to traditional control flow). If you start with an application, it might require other classes as well, like helper and utility classes.
So, in basic Java, the application class would instantiate the helper and utility classes and then start using them, increasing the coupling between them.
-
The application class now depends upon the correct implementation of helper and utility classes, and also, there is no concept of abstraction among the classes.
-
This makes it difficult to test the application class alone, as it will always instantiate the other two classes.
- This is now when the spring dependency injection container comes into the picture.
With the help of spring dependency injection, you will have the same classes to run your application but rather than instantiating and binding the classes; you will have to instruct the spring DI container to do the same for you.
=> This can be done using annotations in the code or using configuration code or XML configuration code.
Types of Spring Dependency Injection
There are three kinds of Dependency Injection in Spring boot:
- Setter Dependency Injection
- Constructor Dependency Injection
- Field Dependency Injection
We will explain the Setter and Constructor Dependency injection below:
1. Setter Dependency Injection
In this type, a Setter method provides the class with dependencies. It refers to the @Autowired annotation on the top of the setter method of the class. Let us take an example below.
Let us take an example of the TeacherMasterDetails class below:
import org.springframework.stereotype.Component;
import lombok.Getter;
import lombok.ToString;
import lombok.Setter;
@Component
@Getter
@Setter
@ToString
public class TeacherMasterDetails{
private int teacherID;
private String teacherName;
private String teacherdept;
}
Also, a SchoolMasterDetails class is as follows:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
@ResstController
public class SchoolMasterDetails{
private TeacherMasterDetails teachmastdetails;
@Autowired
public void setTeachMasterDetails(TeacherMasterDetails teachmastdetails){
this.teachmastdetails = teachmastdetails;
}
@Override
public String toString(){
return "SchoolMasterDetails [teachmastdetails="+teachmastdetails+"]";
}
}
The Autowiring occurs here using the setter method in the SchoolMasterDetails class. The bean object is created for the TeacherMasterDetails class and injected via the setter method in the SchoolMasterDetails class.
2. Constructor Dependency Injection
Here, a class constructor provides dependencies. It refers to the @Autowired annotation on the top of the class constructor.
For example, for the same TeacherMasterDetails class used above, the SchoolMasterDetails class will be as follows:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
@ResstController
public class SchoolMasterDetails{
private TeacherMasterDetails teachmastdetails;
@Autowired
public SchoolMasterDetails(TeacherMasterDetails teachmastdetails){
this.teachmastdetails = teachmastdetails;
}
@Override
public String toString(){
return "SchoolMasterDetails [teachmastdetails="+teachmastdetails+"]";
}
}
Here, the TeacherMasterDetails class object has been Autowired into the SchoolMasterDetails class constructor. Thus, the bean object for TeacherMasterDetails is injected into the SchoolMasterDetails constructor.
3. Field Dependency Injection
In Field Dependency Injection, dependencies are directly injected into a class's fields using the @Autowired annotation. This eliminates the need for setter methods or constructors, making the code concise. However, field injection is considered less flexible compared to constructor injection, as it makes unit testing and dependency management more challenging.
For example, using the same TeacherMasterDetails class, the SchoolMasterDetails class will be as follows:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class SchoolMasterDetails {
@Autowired
private TeacherMasterDetails teachmastdetails;
@Override
public String toString() {
return "SchoolMasterDetails [teachmastdetails=" + teachmastdetails + "]";
}
}
Here, the TeacherMasterDetails bean is automatically injected into the SchoolMasterDetails class through field injection using the @Autowired annotation. Since Spring directly injects the dependency into the field, no constructor or setter method is needed.
Example of Spring Dependency Injection
The following is a code example where we make two classes, namely Person and Address.
Here we are injecting a dependency between the Person and Address classes where the Person class has an Address attribute, so the class depends on Address.
Code in Java
Java
public class Person
{
private Address address;
// Here, we have an attribute that is actually an object of another class
public Person(Address address)
{
this.address = address;
}
// Here, we are setting the address attribute.
// We are using a setter function to set the dependency,
// so it is a Setter Dependency Injection
public void setAddress(Address address)
{
this.address = address;
}
public Address getAddress()
{
return address;
}
}
public class Address
{
private String Street;
private String city;
private String state;
public Address(String street, String city, String state)
{
this.street = street;
this.city = city;
this.state = state;
}
public String getStreet()
{
return street;
}
public String getCity()
{
return city;
}
public String getState()
{
return state;
}
public void setStreet(String street)
{
this.street = street;
}
public void setCity(String city)
{
this.city = city;
}
public void setState(String state)
{
this.state = state;
}
}
public class Main {
public static void main(String[] args) {
// Create an Address object
Address address = new Address("123 Elm Street", "Springfield", "IL");
// Create a Person object and inject the Address dependency
Person person = new Person(address);
// Print out the Address information from the Person object
System.out.println("Street: " + person.getAddress().getStreet());
System.out.println("City: " + person.getAddress().getCity());
System.out.println("State: " + person.getAddress().getState());
}
}

You can also try this code with Online Java Compiler
Run Code
Output
Street: 123 Elm Street
City: Springfield
State: IL
Explanation
Here we can clearly see that we are using setter functions to initialize the attributes in the classes, so here is a Setter Dependency Injection because the setter function setAddress() takes care of the address dependency by initializing an object of the address class.
Need for Dependency Injection
The following are some points that provide the need for the usage of dependency injection:
Highly Extensible Code
Because of the externally injected dependencies, the programmers are able to scale up the application without managing dependencies manually for each function. This makes the process more efficient and helps update the application with far less effort.
Testable Code
It helps the programmers write the test cases easily. They can use mock databases with the dependency injection and test it without hindering the actual database.
Reusable Code
It helps reuse the logic and implementation of the codes. You can create a plug-and-play kind of module to reuse your codes.
Maintainable Code
By using a loosely coupled design, it provides high maintenance to the code. It drastically reduces the cost of ownership.
Inversion of Control
It is a form of Inversion of Control. The control here is inverted to a component of high level, for the handling of creation and injection of the dependencies.
Uses of Spring Dependency Injection
Now let's discuss some uses of Dependency Injection:
-
Dependency injection is a design pattern that promotes loose coupling between classes by allowing dependencies to be injected from outside of the class.
-
Dependency injection can be implemented using either constructor injection, setter injection, or interface injection.
-
Dependency injection promotes code reuse and modularity by separating concerns and allowing components to be easily swapped out.
- Dependency injection is a core concept in the Spring framework and is used extensively in Spring-based applications.
Frequently Asked Questions
Which dependency injection is best in Spring?
We can say that the constructor dependency injection is best in Spring for various reasons. It has better readability, supports immutability, and is state-safe(the object is instantiated to the entire state or not at all).
What type of dependency injection is used in Spring Boot?
In Spring Boot, primarily, Constructor-based dependency injection is used. Here, dependencies are injected using the class constructor. The Spring Framework manages the creation and injection of the dependencies when the dependencies of the class, as constructor parameters, are defined.
Why is Dependency Injection used?
Dependency Injection is used to achieve loose coupling, improve code maintainability, enhance testability, and manage dependencies efficiently in large-scale applications.
How many types of Dependency Injection are there in Spring?
Spring supports three types of Dependency Injection: Constructor Injection, Setter Injection, and Field Injection, each providing different ways to inject dependencies into a class.
Conclusion
Spring Dependency Injection is a very flexible and efficient way of managing dependencies of objects and classes. By allowing objects to be created and wired together dynamically, developers can achieve loose coupling, improved testability, and maintainability in their applications.
Recommended Readings:
You can also consider our Spring Boot Course to give your career an edge over others.