[Java] @Resource vs @Autowired 의존성 주입 비교
Spring에서 의존성을 주입할 때, 둘을 혼동해서 사용하는데 그 차이에 대해 정확히 살펴보자.
@Autowired
- Spring 프레임워크 전용 DI(Dependency Injection)* 방식
- 타입 기반 자동 주입으로, 스프링 컨테이너에서 타입이 일치하는 빈을 자동으로 주입.
- @Qualifier 와 같이 사용하여 이름 지정 가능.
- required=false 로 주입 실패 허용 가능.
- 단, @Autowired(required = false)와 @Qualifier를 함께 쓰는 경우 해당 이름의 Bean이 없으면 조용히 null이 주입되므로 NPE를 피하려면 반드시 null 체크 로직을 함께 구현해야 함.
@Autowired
private PersonService personService;
@Autowired
@Qualifier("personService")
private PersonService personService;
DI(Dependency Injection)란?
- 객체가 필요로 하는 다른 객체를 외부에서 받아 사용하는 방식.
- 객체 간의 의존성을 외부에서 주입하여 결합도를 낮추고 우연성을 높이는 디자인 패턴.
@Resource
- JDK 표준(javax.annotation.Resouce)에서 제공하는 어노테이션
- 이름 기반 주입으로, @Resource(name="beanName") 형식으로 지정하면, 이름으로 매칭된 빈을 주입.
- 이름이 없다면 필드명으로 자동 추론하여 이름 기반 주입 시도.
- 인터페이스를 구현한 클래스에 @Service("beanName")을 명시하지 않으면, 이름 매칭 실패로 자동으로 빈을 주입하지 못할 수 있음.
@Resource(name = "personService")
private PersonService personService;
@Autowired vs @Resource
@Autowired | @Resource | |
표준 | Spring 전용 | JSR-250(Java 표준) |
주입 방식 | 타입 기준 | 이름 기준 |
사용 시 이름 지정 | @Qualifier 필요 | name 속성 사용 |
유연성 | 유연하고 스프링 친화적 | 이름이 정확히 일치해야 함 |
같은 타입의 Bean이 2개 일 때 비교
1. 기본 구조
01) MessageService.java
public interface MessageService {
void send(String message);
}
02) EmailService.java
@Service("emailService")
public class EmailService implements MessageService {
public void send(String message) {
System.out.println("Email: " + message);
}
}
03) SmsService.java
@Service("smsService")
public class SmsService implements MessageService {
public void send(String message) {
System.out.println("SMS: " + message);
}
}
2. 비교
NotificationManager.java
@Component
public class NotificationManager {
@Autowired
private MessageService autoWiredMessageService; // 오류 발생
@Resource(name = "emailService")
private MessageService resourceMessageService; // 정상 동작
public void notifyAll(String msg) {
autoWiredMessageService.send("[Autowired] " + msg);
resourceMessageService.send("[Resource] " + msg);
}
}
01) @Autowired
- 같은 타입의 Bean이 2개 이상 존재하면 어떤 것을 주입해야 할지 모호해져 NoUniqueBeanDefinitionException 오류 발생.
- 해결 방법 : @Qualifier("smsService") 로 이름 명시.
02) @Resource
- 이름 기준 자동 주입으로, name의 빈을 찾아 주입 성공
✅ 정리하자면,
@Autowired 는 Spring에 특화된 타입 기반 주입이고,
@Resource 는 Java 표준의 이름 기반 주입 방식입니다.
상황에 따라 적절히 선택하거나, 다중 빈 상황에서는 @Qualifier, @Primary, 또는 @Resource(name=...)로 명확히 지정하는 것이 중요.