In simple terms DI means that objects do not initiate their dependencies directly. Instead they recive them from an external source.
- When class A uses some functionality of class B, then its said that class A has a dependency of class B.
What is DI in Spring Framework?
Dependency Injection (DI) is a fundamental concept in Spring Framework that makes it possible to develop loosely coupled and easily testable code. In this blog, we'll explore what dependency injection is, how it works in Spring Boot, and provide examples to illustrate its usage.
There are three main types of dependency injection:
- Constructor Injection
- Setter Injection
- Field Injection
Constructor Injection
This is the most recommended way to acheive DI in Spring.It ensures that the dependency is not null and makes the class immutable.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class TestService {
private final TestRepository repository;
@Autowired
public TestService(TestRepository repository) {
this.repository = repository;
}
public void performService() {
repository.doSomething();
}
}
In the example above, TestService class declares a dependency on TestRepository. The dependency is injected via the constructor, which is annotated with @Autowired.
Setter Injection
Setter injection allows the dependency to be injected through a setter method. This method is less preferred than constructor injection because it allows the object to be in an incomplete state.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class TestService {
private TestRepository repository;
@Autowired
public void setTestRepository(TestRepository repository) {
this.repository = repository;
}
public void performService() {
repository.doSomething();
}
}
In this example, TestService class has a setter method setTestRepository, which is used to inject the TestRepository dependency.
Field Injection
Field injection is the least preferred method because it makes the class less testable and harder to maintain. It involves annotating the dependency field directly with @Autowired.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class TestService {
@Autowired
private TestRepository repository;
public void performService() {
repository.doSomething();
}
}
Here, TestRepository is injected directly into the field of TestService using @Autowired.
Qualifiers
When there are multiple beans of the same type, you can use @Qualifier to specify which bean should be injected.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service
public class TestService {
private final TestRepository myRepository;
@Autowired
public TestService(@Qualifier("specificRepository")TestRepository repository) {
this.repository = repository;
}
public void performService() {
repository.doSomething();
}
}
In this example, @Qualifier("specificRepository") specifies that a particular implementation of TestRepository should be injected.
Conclusion
Dependency Injection is a powerful pattern that helps to create loosely coupled, maintainable, and testable applications. Spring Boot leverages dependency injection to manage the lifecycle and configuration of application components, making development more straightforward and efficient. By understanding and applying constructor, setter, and field injection, as well as using qualifiers when necessary, you can create robust Spring Boot applications.
References
https://www.baeldung.com/spring-dependency-injection
https://www.baeldung.com/inversion-control-and-dependency-injection-in-spring
https://docs.spring.io/spring-framework/reference/core/beans/dependencies/factory-collaborators.html
Github : https://github.com/tharindu1998/SpringDependencyInjection
Top comments (0)