Backend Development 6 min read

Understanding @Autowired Injection Issues and Alternative Approaches in Spring

This article explains the initialization order of Java classes, the pitfalls of using @Autowired for dependency injection, compares it with @Resource, and demonstrates setter, constructor, and Lombok-based injection methods with code examples to help avoid null‑pointer exceptions and improve coupling.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Understanding @Autowired Injection Issues and Alternative Approaches in Spring

Problem Cause

The issue stems from the order of class initialization in Java and the timing of @Autowired injection, which occurs after the subclass constructor, potentially leading to null‑pointer exceptions if misused.

1. Initialization Issue

Java class initialization order is:

Parent static fields → Parent static blocks → Child static fields → Child static blocks → Parent instance fields → Parent instance blocks → Parent constructor → Child instance fields → Child instance blocks → Child constructor

@Autowired injection is queued after the child constructor; Spring IOC does not check for null beans, and the JVM does not raise compile‑time errors, but runtime NPE may occur.

2. Over‑strong IOC Dependency

@Autowired is provided by Spring, while @Resource comes from JSR‑250 and is a standard Java annotation. The former creates a strong coupling to the Spring framework, causing warnings and making it hard to switch to another IOC container, whereas the latter does not warn.

3. Other Considerations

Common criticisms include excessive hidden dependencies that violate the Single Responsibility Principle and the inability to inject immutable objects via field injection; these issues should be judged based on actual development context.

Alternative Usage Methods

Besides @Autowired , other viable options exist:

1. Setter Injection

@RestController
public class TestController2 {
    ITestService testService;
    /* Based on setter injection */
    @Autowired
    public void setTestService(ITestService iTestService) {
        this.testService = iTestService;
    }
    @GetMapping("/status2")
    public Result
status() {
        return testService.status();
    }
}

This uses @Autowired on the setter method rather than directly on the field.

2. Constructor Injection

@RestController
public class TestController1 {
    ITestService testService;
    /* Based on constructor injection */
    public TestController1(ITestService iTestService) {
        this.testService = iTestService;
    }
    @GetMapping("/status1")
    public Result
status() {
        return testService.status();
    }
}

Constructor injection avoids circular dependencies and is considered the most reliable method.

3. Simplified Constructor with Lombok (Recommended)

First, add Lombok dependency:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.2</version>
</dependency>

Then use @RequiredArgsConstructor on the class; final fields are required.

@RestController
@RequiredArgsConstructor
public class TestController3 {
    /* Using @RequiredArgsConstructor, can also be applied to service layer */
    private final ITestService testService;
    @GetMapping("/status3")
    public Result
status() {
        return testService.status();
    }
}

IDEA’s Structure panel can be used to view the generated constructor.

Summary

In practice, constructor injection—especially when combined with Lombok—provides a clean and reliable way to inject dependencies while keeping the code concise.

BackendJavaSpringdependency injectionAutowiredResourceLombok
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

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.