1. Introduction
The @Resource annotation is part of the Java EE (now Jakarta EE) standard. It allows Spring to perform dependency injection similar to @Autowired, but with slightly different behavior—especially in how beans are resolved.
2. What is @Resource?
@Resourceis defined in thejavax.annotationpackage.- It is part of the JSR-250 specification.
- Spring supports it via its own bean injection framework.
Import Statement
import javax.annotation.Resource;
3. Behavior of @Resource
Spring handles @Resource by name first, and by type second (if no name match is found).
Injection Order:
- By name: If a bean with the same name as the field/method is found, it is injected.
- By type: If no name match is found, Spring tries to match by type.
- Failure: If neither is found, an error is thrown.
4. How to Use @Resource
A. Field Injection
@Component
public class NotificationService {
@Resource
private EmailService emailService;
public void send(String to, String msg) {
emailService.sendEmail(to, msg);
}
}
B. Setter Injection
@Component
public class NotificationService {
private EmailService emailService;
@Resource
public void setEmailService(EmailService emailService) {
this.emailService = emailService;
}
}
C. Specifying Bean Name
If multiple beans of the same type exist, you can resolve ambiguity using the name attribute:
@Component("smsService")
public class SMSService implements MessageService {
public void sendMessage(String msg) {
System.out.println("SMS: " + msg);
}
}
@Component
public class NotificationService {
@Resource(name = "smsService")
private MessageService messageService;
}
5. Comparison with @Autowired and @Inject
| Feature | @Resource | @Autowired | @Inject |
| Package | javax.annotation | org.springframework.beans.factory.annotation | javax.inject |
| Dependency type | By name, then by type | By type, then qualifier | By type, qualifier optional |
| Optional dependency | Not supported | @Autowired(required = false) | Not supported |
| Supports qualifiers | Yes, using @Resource(name="") | Yes, using @Qualifier | Yes, using @Named |
| Framework independent | Java EE standard | Spring-specific | JSR-330 standard |
| Preferred for… | Legacy or portable code | Full Spring apps | Portable code |
6. Use Case Examples
Example with Multiple Implementations
public interface MessageService {
void send(String msg);
}
@Component("emailService")
public class EmailService implements MessageService {
public void send(String msg) {
System.out.println("Email: " + msg);
}
}
@Component("smsService")
public class SMSService implements MessageService {
public void send(String msg) {
System.out.println("SMS: " + msg);
}
}
@Component
public class NotificationService {
@Resource(name = "emailService")
private MessageService messageService;
public void notifyUser(String msg) {
messageService.send(msg);
}
}
7. Important Notes and Limitations
@Resourcedoes not support constructor injection.- If the field name doesn’t match any bean name, Spring will try to match by type.
- Cannot mark the dependency as optional.
- Works well when bean names are unique or you want to inject by name.
8. When Should You Use @Resource?
Use @Resource when:
- You want to inject a bean by name
- You’re working on a Java EE standard-based application
- You need to write portable code compatible with other containers like Java EE servers (TomEE, GlassFish)
- You prefer Java standard annotations over Spring-specific ones
But in modern Spring applications, @Autowired or @Inject with constructor injection is preferred.
9. Best Practices
- Avoid using
@Resourcefor constructor injection (not supported) - Prefer using
@Resource(name = "...")when multiple beans of the same type exist - Stick to one injection style (
@Autowired,@Inject, or@Resource) in a project for consistency - Use meaningful bean names to avoid confusion when injecting by name
