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.

Java Backend Technology
Java Backend Technology
Java Backend Technology
When to Use @Autowired, @Resource, or @Inject? A Deep Dive into Spring DI

Introduction

The article explores three Spring dependency‑injection annotations— @Autowired, @Resource, and @Inject —and explains when each should be used.

@Autowired

@Autowired

is 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

@Inject

comes 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

@Resource

is 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.

Spring DI diagram
Spring DI diagram

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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Javaspringdependency-injectionAutowiredresourceInject
Java Backend Technology
Written by

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!

0 followers
Reader feedback

How this landed with the community

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.