[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의 빈을 찾아 주입 성공

    ✅ 정리하자면,

     

    @AutowiredSpring에 특화된 타입 기반 주입이고,
    @Resource Java 표준의 이름 기반 주입 방식입니다.

    상황에 따라 적절히 선택하거나, 다중 빈 상황에서는 @Qualifier, @Primary, 또는 @Resource(name=...)로 명확히 지정하는 것이 중요.

    댓글