Backend Development 7 min read

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.

<code>@Controller
public class UserController {
    @Autowired
    private UserService userService;
}</code>

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.

<code>@Controller
public class UserController {
    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }
}</code>

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.

<code>@Controller
public class UserController {
    private UserService userService;

    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
}</code>

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.

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

login 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.