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
?
@Resource
is defined in thejavax.annotation
package.- 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
@Resource
does 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
@Resource
for 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