Understanding @Resource in Spring Boot: Why 90% of Developers Misuse It
The article explains the JSR‑250 @Resource annotation in Spring Boot, detailing its name‑first injection logic, differences from @Autowired, common pitfalls with multiple implementations, and proper usage patterns—including explicit name specification and why constructor injection is preferred—providing code examples and interview‑ready explanations.
Many Java developers are familiar with @Autowired but often give vague answers when asked about @Resource. Understanding the parsing logic behind @Resource demonstrates that you not only know how to use Spring, but also understand its inner workings.
What is @Resource ?
@Resourcecomes from the JSR‑250 specification (a Java standard) and is not defined by Spring itself. Spring merely provides an implementation that allows the annotation to participate in its dependency‑injection mechanism. Its core characteristics are:
Java standard annotation
Supported by Spring
Injection priority: name first , then type
How Spring resolves @Resource
When the Spring container starts and encounters @Resource, it follows a fixed three‑step process:
Step 1: Look for a bean with the same name.
Step 2: If not found, look for a bean of the required type.
Step 3: If still not found, throw an exception.The priority is therefore Name → Type , which is the root cause of many common pitfalls.
Simple example (name priority)
Assume the following project structure:
/usr/local/project/src/main/java/com/icoderoad/serviceDefine an interface:
package com.icoderoad.service;
public interface PaymentService {
void pay();
}Implementation class:
package com.icoderoad.service.impl;
import org.springframework.stereotype.Component;
import com.icoderoad.service.PaymentService;
@Component
public class DefaultPaymentService implements PaymentService {
@Override
public void pay() {
System.out.println("default payment...");
}
}Consumer class using @Resource:
package com.icoderoad.order;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;
import com.icoderoad.service.PaymentService;
@Component
public class OrderService {
@Resource
private PaymentService paymentService;
}Resolution steps:
Search for a bean named paymentService – not found.
Search for a bean of type PaymentService – exactly one bean ( DefaultPaymentService) is found, so injection succeeds.
Multiple‑implementation scenario (common interview trap)
Two implementations are defined:
package com.icoderoad.service.impl;
import org.springframework.stereotype.Component;
import com.icoderoad.service.PaymentService;
@Component("upiPayment")
public class UpiPaymentService implements PaymentService {
@Override
public void pay() {
System.out.println("upi payment...");
}
}
@Component("cardPayment")
public class CardPaymentService implements PaymentService {
@Override
public void pay() {
System.out.println("card payment...");
}
}Now the container holds two PaymentService beans. Using the same @Resource declaration as before leads to:
Step 1: No bean named paymentService exists.
Step 2: Two beans of type PaymentService are found.
Step 3: Spring throws NoSuchBeanDefinitionException.
Correct usage (explicit name)
@Resource(name = "upiPayment")
private PaymentService paymentService;Because the name matches a bean, the first step succeeds and the type‑search step is never reached, resulting in successful injection.
Comparison: @Resource vs @Autowired
Source : JSR‑250 vs Spring.
Default injection : name‑first vs type‑first.
Constructor support : not supported vs supported.
Recommendation : legacy projects vs preferred for new projects.
Can @Resource be used on constructors?
No. It only supports field injection and setter injection. Modern Spring Boot strongly recommends constructor injection:
package com.icoderoad.order;
import org.springframework.stereotype.Component;
import com.icoderoad.service.PaymentService;
@Component
public class OrderService {
private final PaymentService paymentService;
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
}Advantages of constructor injection include immutable dependencies, easier unit testing, and avoidance of circular dependencies.
When is @Resource still useful?
Maintaining older Java EE projects.
Ensuring compatibility with legacy code.
When the bean name is explicitly known.
Interview scenarios that focus on name‑first injection.
Common misconceptions
Many developers mistakenly believe @Resource and @Autowired are identical. The most frequent error is forgetting the name‑first priority, which in multi‑implementation cases leads to NoSuchBeanDefinitionException and wasted debugging time.
Interview‑level summary
@Resource is a Java standard annotation that injects by name first, falls back to type matching, and does not support constructor injection.
Conclusion
Being able to write @Resource is only a surface skill. Understanding its resolution order, injection strategy, origin, and how it differs from @Autowired demonstrates deeper framework knowledge and moves you from a mere API user to a Spring thinker.
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.
LuTiao Programming
LuTiao Programming is a friendly community offering free programming lessons. We inspire learners to explore new ideas and technologies and quickly acquire job-ready skills.
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.
