Understanding @Autowired, @Resource, and @Inject: When to Use Each in Spring
This article explains the differences between Spring's @Autowired, @Resource, and @Inject annotations, the recommended injection methods, how the IDE warns against field injection, and best practices for constructor, setter, and field injection to write clean, maintainable Java code.
Introduction
This chapter explores key points of dependency injection in Spring development, focusing on three annotations: @Autowired, @Resource, and @Inject.
Difference between @Autowired, @Resource, and @Inject
Spring supports using these three annotations for dependency injection. Below are their distinctions.
@Autowired
@Autowired is provided by Spring and requires importing org.springframework.beans.factory.annotation.Autowired.
Example code:
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");
}
}
@Service
public class SvcC implements Svc {
@Override
public void sayHello() {
System.out.println("hello, this is service C");
}
}Test class:
@SpringBootTest
public class SimpleTest {
@Autowired
// @Qualifier("svcA")
Svc svc;
@Test
void rc() {
Assertions.assertNotNull(svc);
svc.sayHello();
}
}Assembly order:
Search for a bean matching the type in the context.
If multiple beans exist, match by name.
If still ambiguous, an error is thrown unless @Autowired(required=false) is set.
@Inject
In Spring, @Inject and @Autowired are processed by AutowiredAnnotationBeanPostProcessor and behave the same. @Inject is defined by JSR‑330 and can also be used with Guice.
@Inject belongs to the JSR‑330 specification. When using it, you can switch to Guice if needed.
Guice is Google’s lightweight DI framework.
The main differences are that @Inject is in the Java EE package and does not have a required attribute, whereas @Autowired can set required=false.
@Resource
@Resource is defined by JSR‑250 and is handled by Spring's CommonAnnotationBeanPostProcessor. It has two important attributes: name and type. The name resolves to the bean name, while type resolves to the bean type.
Assembly order for @Resource:
If both name and type are specified, Spring looks for a unique matching bean; otherwise an exception is thrown.
If only name is specified, Spring matches by bean name.
If only type is specified, Spring matches by type; multiple or zero matches cause an exception.
If neither is specified, Spring defaults to byName then byType.
IDEA Warning: "Field injection is not recommended"
When using @Autowired on a field, IntelliJ IDEA shows a warning recommending constructor injection and asserting mandatory dependencies.
Field injection is not recommended. Inspection info: Spring Team Recommends: "Always use constructor based dependency injection in your beans. Always use assertions for mandatory dependencies".
IDEA can automatically convert the field injection to constructor injection using Alt+Enter.
@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();
}
}The Spring team suggests using constructor injection for mandatory dependencies and setter injection for optional ones.
Three Ways of Dependency Injection in Spring
Field injection (property injection)
Setter injection
Constructor injection
1. Field Injection
Injects directly into the field via reflection. Simple but discouraged by the Spring team.
@Autowired
private Svc svc;2. Setter Injection
Injects via a setter method. Since Spring 4.3, @Autowired on a setter can be omitted.
private Helper helper;
@Autowired
public void setHelper(Helper helper) {
this.helper = helper;
}3. Constructor Injection
All required dependencies are passed through the constructor, allowing final fields and guaranteeing non‑null values.
private final Svc svc;
@Autowired
public HelpService(@Qualifier("svcB") Svc svc) {
this.svc = svc;
}Spring recommends constructor injection because it enables immutable components, ensures required dependencies are not null, and makes beans fully initialized before use. A large number of constructor arguments may indicate a code smell.
Since you can mix constructor‑based and setter‑based DI, use constructors for mandatory dependencies and setters for optional ones.
Summary
Understanding the differences between @Autowired, @Resource, and @Inject, as well as the pros and cons of 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 Interview Crash Guide
Dedicated to sharing Java interview Q&A; follow and reply "java" to receive a free premium Java interview guide.
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.
