Why @Autowired and Constructor Injection Differ in Spring: Execution Order & final Keyword Explained
This article explains the warning caused by @Autowired, compares field injection with constructor injection, clarifies Java's initialization order, shows how to fix the issue using constructor injection, and discusses whether adding the final modifier to injected fields is necessary.
Problem Background
When using @Autowired on a field, IntelliJ IDEA may display a warning that the injected value could be null. The warning can be suppressed, but the root cause is that field injection occurs after the constructor finishes, so the field is not available during object construction.
Spring team recommends always using constructor‑based dependency injection and assertions for mandatory dependencies.
Difference Between @Autowired and Constructor Injection
@Autowiredcan be applied to fields, setter methods, or constructors. Field injection works like setter injection defined in XML, while constructor injection supplies dependencies directly via the class constructor.
Java initialization order is:
static fields/blocks → instance fields/blocks → constructor → @Autowired injection
Consequently, accessing an @Autowired field inside the constructor sees a null value, which can cause a NullPointerException during bean creation.
Typical exception message:
Exception in thread “main” org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘…’: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate […]: Constructor threw exception; nested exception is java.lang.NullPointerException
Solution: Use Constructor Injection
Define a constructor that receives all required beans. Spring injects the dependencies before the constructor body runs, guaranteeing that the fields are fully initialized.
@Component
public class MyService {
private final Dependency dependency;
@Autowired
public MyService(Dependency dependency) {
this.dependency = dependency;
}
}Why Add final ?
Spring beans are singleton by default; the instance is created once at startup. Marking a dependency field as final does not change the bean lifecycle but documents that the reference will not be reassigned after construction.
It makes the code clearer and helps static‑analysis tools detect accidental reassignment.
Reference: https://blog.csdn.net/ruangong1203/article/details/50992147
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
JavaEdge
First‑line development experience at multiple leading tech firms; now a software architect at a Shanghai state‑owned enterprise and founder of Programming Yanxuan. Nearly 300k followers online; expertise in distributed system design, AIGC application development, and quantitative finance investing.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
