Why Constructor Injection Outperforms Field and Setter Injection in Spring

This article explains Spring's three dependency injection methods—field, constructor, and setter—examines why IntelliJ IDEA warns against field injection, and compares them across reliability, maintainability, testability, flexibility, cycle detection, and performance, concluding that constructor injection is generally the preferred approach.

macrozheng
macrozheng
macrozheng
Why Constructor Injection Outperforms Field and Setter Injection in Spring

Spring's Three Dependency Injection Methods

The @Autowired annotation is familiar to every Spring developer, but IntelliJ IDEA often underlines it with a warning that "Field injection is not recommended".

IDE warning screenshot
IDE warning screenshot

Field Injection

Using @Autowired directly on a field is the classic field injection style.

@Controller
public class UserController {
    @Autowired
    private UserService userService;
}

This approach relies on Java reflection, allowing even private members to be injected.

Constructor Injection

Constructor injection is the most recommended way in everyday development.

@Controller
public class UserController {
    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }
}

It establishes dependencies during object construction, enforcing a strict creation order; Spring resolves circular dependencies automatically unless they cause an exception.

Setter Injection

Setter injection also uses @Autowired, but applies it to a setter method rather than directly on the field.

@Controller
public class UserController {
    private UserService userService;

    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
}

This method injects the dependency via the setter, making the relationship explicit.

Comparison of the Three DI Methods

After understanding the three injection styles, we revisit why IDEA discourages field injection and compare the approaches on several dimensions.

Reliability Field Injection: unreliable Constructor Injection: reliable Setter Injection: unreliable

Constructor injection guarantees that all required dependencies are satisfied at construction time, preventing later null‑pointer issues.

Maintainability Field Injection: poor Constructor Injection: good Setter Injection: poor

Constructor injection makes dependencies explicit in the signature, which is easier to read and analyze.

Testability Field Injection: poor Constructor Injection: good Setter Injection: good

Both constructor and setter injection facilitate mocking and unit testing, whereas field injection makes it harder.

Flexibility Field Injection: very flexible Constructor Injection: inflexible Setter Injection: very flexible

Field and setter injection allow more flexible wiring but can lead to chaotic designs; constructor injection enforces a strict order.

Cycle Detection Field Injection: not detected Constructor Injection: automatically detected Setter Injection: not detected

Spring can detect circular dependencies only with constructor injection.

Performance Field Injection: fast startup Constructor Injection: slower startup Setter Injection: fast startup

The stricter ordering of constructor injection prolongs application startup time.

DI comparison table
DI comparison table

Overall, constructor injection excels in most aspects and is usually the first choice. When using @Autowired, opting for setter injection avoids the IDE warning and improves testability.

Conclusion

For dependency injection, Constructor Injection is the preferred method.

When using @Autowired, prefer the Setter Injection style to make the code more unit‑test friendly and eliminate IDE warnings.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

javaspringdependency-injectionConstructor InjectionField InjectionSetter InjectionIDE warnings
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.