Why @Autowired Is Discouraged and When to Prefer @Resource or Constructor Injection

This article explains why the @Autowired field injection in Spring is often discouraged, compares it with @Resource and constructor injection, shows practical code examples and error scenarios, and provides guidance on choosing the most appropriate dependency‑injection method for robust backend development.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Why @Autowired Is Discouraged and When to Prefer @Resource or Constructor Injection

Introduction

In Spring, dependency injection (DI) is essential for wiring beans. The @Autowired annotation is the most familiar way to inject a bean, but IntelliJ IDEA frequently warns that its usage is not recommended. This article examines the reasons behind that warning and clarifies the proper use of field injection.

Why @Autowired Is Not Recommended

Implicit Dependency

@Autowired injects dependencies by type, which can make the required bean ambiguous, especially when multiple candidates of the same type exist, leading to injection failures or wrong beans being injected.

Circular Dependency

Field injection can cause circular dependencies in singleton beans; although Spring provides mechanisms to resolve them, additional handling is still required.

Opaque Lifecycle

Beans injected via @Autowired are managed by Spring, so the class cannot explicitly see the bean’s lifecycle. Constructor injection, by contrast, makes the lifecycle explicit.

Violates Immutability

Field injection allows dependencies to change during an object’s lifetime, whereas constructor injection fixes dependencies at creation time, adhering to immutability principles.

Because of these concerns, many developers replace @Autowired with @Resource, which does not trigger the IDE warning.

@Autowired and @Resource Basic Usage

@Autowired

@Autowired is a Spring annotation that automatically injects a bean based on its type (or name when used with @Qualifier).

@Autowired
private UserService userService;

In this example Spring injects the UserService bean into the userService field.

@Resource

@Resource belongs to the Java specification (javax/jakarta.annotation) and prefers name‑based injection first; if no matching name is found, it falls back to type‑based injection.

@Resource
private UserService userService;

The main difference is that @Resource first looks for a bean named userService before considering the type.

Functionally the two annotations behave the same; only the matching order differs.

Practical Comparison

Consider an interface UserService with two implementations:

@Service
public interface UserService {
    // user service methods
}

@Component
public class UserServiceImpl implements UserService {
    // implementation
}

@Component
public class AnotherUserServiceImpl implements UserService {
    // another implementation
}

Testing with @Autowired

Injecting @Autowired in a test controller:

@RestController("test")
public class TestController {
    @Autowired
    private UserService userService;
}

Running the application yields the error “required a bean but found two beans”. The issue is resolved by specifying the bean name with @Qualifier:

@RestController("test")
public class TestController {
    // @Qualifier("userServiceImpl")
    @Autowired
    private UserService userServiceImpl;
}

After the change the application starts normally and the bean is retrieved successfully.

Testing with @Resource

Injecting @Resource produces the same duplicate‑bean error:

@RestController("test")
public class TestController {
    @Resource
    private UserService userService;
}

Fix it by naming the bean explicitly:

@RestController("test")
public class TestController {
    // @Resource(name = "userServiceImpl")
    @Resource
    private UserService userServiceImpl;
}

The project starts correctly and the bean is obtained.

Both annotations ultimately achieve the same effect; @Autowired may have a slight performance edge due to finer‑grained auto‑wiring control.

Recommended Injection Method

Constructor injection is the preferred approach, especially for complex dependency graphs, immutable objects, and unit testing.

Reasons

Explicit dependencies: Constructor parameters list all required beans, making the code clearer.

Immutability: Dependencies can be declared final, preventing later modification.

Avoids circular dependencies: Problems are detected early during bean creation.

Clear dependency graph: Improves readability and maintainability.

Example

@RestController("test")
public class TestController {
    private final UserService userService;

    public TestController(UserService userService) {
        this.userService = userService;
    }
}

// Lombok alternative
@RestController("test")
@RequiredArgsConstructor
public class TestController {
    private final UserService userService;
}

The example shows how constructor injection makes the dependency explicit and can be simplified with Lombok.

Is Constructor Always Better Than @Autowired?

Simplifies code: No need to write constructors or setters for each dependency.

Rapid development: Direct field injection is quick and flexible.

Automatic dependency management: Spring handles selection and injection.

Avoids long constructors: When many dependencies exist, field injection keeps the class signature short.

Conclusion

Although IDEA warns against @Autowired, it is not inherently a bad choice. Each injection style has its own advantages and drawbacks; the decision should be based on project size, complexity, and team conventions rather than blindly following IDE suggestions.

backend developmentSpringdependency-injectionConstructor Injection@Autowired@Resource
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

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.