When to Use @Autowired, @Resource, or @Inject? A Deep Dive into Spring DI
This article explains the differences between Spring's @Autowired, @Resource, and @Inject annotations, compares field, setter, and constructor injection, shows how Spring resolves bean candidates, and outlines the framework's recommendations for choosing the appropriate injection style.
Introduction
The article explores three Spring dependency‑injection annotations— @Autowired, @Resource, and @Inject —and explains when each should be used.
@Autowired
@Autowiredis a Spring‑specific annotation (package org.springframework.beans.factory.annotation.Autowired). It can be placed on fields, constructors, or setter methods.
public interface Svc {
void sayHello();
}
@Service
public class SvcA implements Svc {
@Override
public void sayHello() {
System.out.println("hello, this is service A");
}
}
@Service
public class SvcB implements Svc {
@Override
public void sayHello() {
System.out.println("hello, this is service B");
}
}When multiple beans of the same type exist, Spring first matches by type, then by bean name, and finally by the field name. The required attribute (default true) can be set to false to avoid an exception if no bean is found.
@Inject
@Injectcomes from JSR‑330. In a Spring context it is processed by the same AutowiredAnnotationBeanPostProcessor as @Autowired, so its behavior is identical except that it does not have a required attribute. It can also be used with other DI containers such as Google Guice.
@Resource
@Resourceis defined by JSR‑250 and is handled by Spring's CommonAnnotationBeanPostProcessor. It supports two attributes: name – resolves to the bean name. type – resolves to the bean type.
Resolution order:
If both name and type are specified, Spring looks for a unique bean matching both.
If only name is specified, it matches by bean name.
If only type is specified, it matches by type.
If neither is specified, Spring falls back to byName then byType.
Injection Styles
Spring supports three injection styles:
Field injection (directly on a member variable).
Setter injection (via a setXxx() method).
Constructor injection (parameters of a constructor annotated with @Autowired).
Field Injection
Simple and concise, but it couples the class to the container, makes unit testing harder, and can hide required dependencies.
@Autowired
private Svc svc;Setter Injection
Allows optional dependencies and re‑configuration, but mandatory dependencies still need null‑checks.
private Helper helper;
@Autowired
public void setHelper(Helper helper) {
this.helper = helper;
}Since Spring 4.3, the @Autowired on a single‑setter can be omitted.
Constructor Injection
Preferred for mandatory dependencies; creates immutable objects and guarantees that all required collaborators are present.
private final Svc svc;
@Autowired
public HelpService(@Qualifier("svcB") Svc svc) {
this.svc = svc;
}From Spring 4.3 onward, if a bean has only one constructor, the @Autowired annotation can be omitted.
IDE Warning
IntelliJ IDEA warns "Field injection is not recommended" and suggests converting to constructor injection. The quick‑fix replaces the field annotation with a constructor that receives the dependency.
@Service
public class HelpService {
private final Svc svc;
@Autowired
public HelpService(@Qualifier("svcB") Svc svc) {
// Assert.notNull(svc, "svc must not be null");
this.svc = svc;
}
public void sayHello() {
svc.sayHello();
}
}Spring Team Recommendations
Constructor injection should be used for mandatory dependencies, while setter injection is suitable for optional ones.
Using constructor injection enforces immutability (via final fields) and eliminates null‑reference problems. A large number of constructor parameters is a code smell indicating that a class has too many responsibilities.
Conclusion
Understanding the nuances of @Autowired, @Resource, and @Inject, as well as the trade‑offs between field, setter, and constructor injection, helps you write cleaner, more maintainable Spring applications.
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.
Java Backend Technology
Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!
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.
