0
0
SpringbootComparisonBeginner · 4 min read

Constructor vs Setter vs Field Injection in Spring Boot: Key Differences

In Spring Boot, constructor injection injects dependencies via a class constructor and is preferred for mandatory dependencies and immutability. Setter injection uses setter methods allowing optional dependencies and flexibility, while field injection injects directly into fields but is less recommended due to testability and design concerns.
⚖️

Quick Comparison

Here is a quick side-by-side comparison of constructor, setter, and field injection in Spring Boot.

FactorConstructor InjectionSetter InjectionField Injection
Injection MethodVia constructor parametersVia setter methodsDirectly on fields
Dependency RequirementMandatory dependenciesOptional or changeable dependenciesUsually mandatory but less explicit
ImmutabilitySupports immutable fieldsFields can be mutableFields can be mutable
TestabilityEasier to test with explicit dependenciesTestable but requires settersHarder to test, uses reflection
Spring RecommendationPreferred and recommendedAcceptable for optional dependenciesNot recommended, considered bad practice
Null SafetyDependencies are guaranteed non-null after constructionDependencies can be null if setter not calledDependencies can be null if injection fails
⚖️

Key Differences

Constructor injection requires all dependencies to be provided when the object is created. This makes the dependencies explicit and the object immutable after creation, which improves code safety and clarity. Spring automatically calls the constructor with the required beans.

Setter injection uses setter methods to inject dependencies after the object is created. This allows optional dependencies or changing dependencies later but can lead to partially initialized objects if setters are not called. It also makes the object mutable.

Field injection injects dependencies directly into private fields using reflection and annotations like @Autowired. While it reduces boilerplate code, it hides dependencies, makes testing harder, and breaks encapsulation. For these reasons, Spring recommends constructor injection over field injection.

⚖️

Code Comparison: Constructor Injection

java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class ServiceA {
    private final ServiceB serviceB;

    @Autowired
    public ServiceA(ServiceB serviceB) {
        this.serviceB = serviceB;
    }

    public String serve() {
        return "ServiceA uses " + serviceB.action();
    }
}

@Component
class ServiceB {
    public String action() {
        return "ServiceB";
    }
}
Output
ServiceA uses ServiceB
⚖️

Code Comparison: Setter Injection Equivalent

java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class ServiceA {
    private ServiceB serviceB;

    @Autowired
    public void setServiceB(ServiceB serviceB) {
        this.serviceB = serviceB;
    }

    public String serve() {
        return "ServiceA uses " + serviceB.action();
    }
}

@Component
class ServiceB {
    public String action() {
        return "ServiceB";
    }
}
Output
ServiceA uses ServiceB
🎯

When to Use Which

Choose constructor injection when dependencies are mandatory and you want immutable, clear, and testable code. It is the best practice and recommended by Spring.

Choose setter injection when dependencies are optional or might change after object creation, but be cautious about partial initialization.

Avoid field injection because it hides dependencies, reduces testability, and breaks encapsulation, making your code harder to maintain.

Key Takeaways

Constructor injection is preferred for mandatory dependencies and immutability.
Setter injection suits optional dependencies but can lead to mutable objects.
Field injection is discouraged due to poor testability and hidden dependencies.
Explicit dependencies improve code clarity and testing ease.
Follow Spring's recommendation: use constructor injection whenever possible.