Spring Framework
Programming
Java Annotations
Dependency Injection
Code Comparison

Resource vs Autowired

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

@Autowired and @Resource can both inject dependencies in a Spring application, but they do not follow the same matching rules or convey the same intent. Understanding that difference matters because injection problems usually appear only after a project has several beans of the same type.

The main difference: type versus name

The shortest summary is:

  • '@Autowired is Spring-native and primarily resolves by type'
  • '@Resource comes from Jakarta annotations and is primarily name-oriented'

With @Autowired, Spring looks for a compatible bean type:

java
1@Service
2public class BillingService {
3
4    private final PaymentGateway gateway;
5
6    public BillingService(PaymentGateway gateway) {
7        this.gateway = gateway;
8    }
9}

If there is exactly one PaymentGateway bean, injection is easy. If there are multiple candidates, you usually add @Qualifier.

By contrast, @Resource is often used when the bean name itself is the important selection rule:

java
1import jakarta.annotation.Resource;
2
3@Service
4public class BillingService {
5
6    @Resource(name = "stripeGateway")
7    private PaymentGateway gateway;
8}

That asks Spring for a bean with a specific name.

Why constructor injection changes the conversation

In modern Spring code, constructor injection is usually the best default. It makes dependencies explicit, helps testing, and avoids hidden mutable state.

That naturally favors @Autowired style semantics, and in many cases you do not even need the annotation on the constructor at all:

java
1@Service
2public class ReportService {
3
4    private final ReportRepository repository;
5
6    public ReportService(ReportRepository repository) {
7        this.repository = repository;
8    }
9}

With a single constructor, Spring can wire it automatically. This is one reason @Autowired feels more natural in modern Spring applications than field-level @Resource.

When @Qualifier and @Resource overlap

If you have multiple beans of the same type, these two styles can look similar:

java
1@Service
2public class BillingService {
3
4    private final PaymentGateway gateway;
5
6    public BillingService(@Qualifier("stripeGateway") PaymentGateway gateway) {
7        this.gateway = gateway;
8    }
9}

and:

java
@Resource(name = "stripeGateway")
private PaymentGateway gateway;

Both point at the same bean, but they communicate intent differently. @Qualifier says "select this named candidate within Spring’s type-based model." @Resource says "inject the named resource."

Practical guidance

For most Spring-only codebases, a strong default is:

  • prefer constructor injection
  • prefer @Autowired semantics, usually with no explicit annotation on a single constructor
  • add @Qualifier when multiple beans share a type

Use @Resource when name-based injection is genuinely what you want, or when working with code that already follows Jakarta-style resource semantics.

The goal is not annotation variety. The goal is making dependency resolution obvious to future readers.

Subtle behavioral differences

There are a few practical distinctions worth remembering:

  • '@Autowired works naturally with constructors, fields, and setters'
  • '@Resource is commonly used on fields and setters, not constructor parameters'
  • '@Autowired integrates closely with Spring features such as @Qualifier'
  • '@Resource emphasizes bean naming more directly'

Those differences matter most in larger applications where dependency graphs and bean names are no longer trivial.

Common Pitfalls

The biggest pitfall is field injection by habit. Whether you use @Autowired or @Resource, hidden field injection makes dependencies less obvious and harder to test than constructor injection.

Another issue is assuming @Resource and @Autowired are interchangeable. They may both inject a bean in simple cases, but ambiguity resolution behaves differently once multiple candidates exist.

People also overuse bean names as architecture. If everything depends on string bean names everywhere, refactoring becomes more fragile than it needs to be.

Finally, do not treat annotation choice as merely stylistic. It reflects how the dependency should be resolved, which directly affects maintainability and debugging.

Summary

  • '@Autowired is Spring-native and primarily resolves dependencies by type.'
  • '@Resource is Jakarta-based and is primarily name-oriented.'
  • Constructor injection is usually the best modern default in Spring applications.
  • Use @Qualifier with @Autowired when multiple beans share the same type.
  • Choose the annotation that matches the resolution rule you actually want, not just the one that seems shorter.

Course illustration
Course illustration

All Rights Reserved.