당니의 개발자 스토리

@Autowired와 @Qualifier 본문

Java, Spring

@Autowired와 @Qualifier

clainy 2026. 5. 6. 16:57

getBean으로 Bean을 꺼낼 때,

만약 같은 타입 Bean이 여러 개 있다면 어떻게 해결할까?

 

Spring에서 DI를 쓰다 보면 자연스럽게 @Autowired를 사용하게 된다.

 

@Autowired는 필요한 Bean을 자동으로 넣어주는 애노테이션이다.

예를 들어 이런 코드가 있다고 해보자.

@Service
public class WasherUser {

    private final Washer washer;

    public WasherUser(Washer washer) {
        this.washer = washer;
    }
}

여기서 Washer 타입 Bean을 Spring이 찾아서 자동으로 넣어준다.

 

이걸 조금 더 풀어서 보면 이렇게 동작한다.

1. Washer 타입을 찾는다
2. Container에서 Bean 검색
3. 하나 있으면 바로 주입

이게 정상적인 흐름이다.

 

그런데 문제가 생기는 경우가 있다.

같은 타입 Bean이 여러 개 있을 때다.

 

예를 들어 이렇게 만들어보자.

@Component
public class SWasher implements Washer {
}
@Component
public class TurboWasher implements Washer {
}

이제 Washer 타입 Bean이 2개다.

 

이 상태에서 기존 코드를 그대로 쓰면 어떻게 될까?

public WasherUser(Washer washer)

Spring 입장에서는 이렇게 된다.

Washer 타입 달라고 했는데 두 개 있는데?

그래서 어떤 걸 넣어야 할지 결정하지 못한다.

그래서 에러가 터진다.

NoUniqueBeanDefinitionException

즉 같은 타입이 여러 개면 자동 주입이 실패한다.

 

이걸 해결하는 방법이 @Qualifier다.

@Qualifier는 Bean이름으로 지정해서 선택하는 방식이다.

 

예를 들어 이렇게 작성한다.

@Component("sWasher")
public class SWasher implements Washer {
}
@Component("turboWasher")
public class TurboWasher implements Washer {
}

그리고 주입할 때 이렇게 쓴다.

public WasherUser(@Qualifier("turboWasher") Washer washer) {
    this.washer = washer;
}

이렇게 하면 SpringturboWasher Bean을 정확하게 찾아서 넣어준다.

 

즉 흐름은 이렇게 바뀐다.

1. 타입으로 후보 찾기 (Washer)
2. 이름으로 필터링 (turboWasher)
3. 최종 Bean 선택

여기서 중요한 점은 자동 주입은 기본적으로 타입 기준이라는 점이다.


@Autowired는 기본적으로 타입으로 Bean을 찾는다.

 

그래서 타입이 하나면 문제가 없지만,
여러 개면 충돌이 발생한다.

 

그래서 선택 기준을 추가로 주는 것이 @Qualifier다.

 

여기서 Bean 이름은 어떻게 정해질까?

@Component를 이렇게 쓰면

@Component
public class SWasher {
}

Bean 이름은 기본적으로 클래스 이름에서 앞글자만 소문자로 바뀐다.

sWasher

이게 기본 이름이다.

 

그래서 @Qualifier에도 이 이름을 넣어야 한다.

@Qualifier("sWasher")

또 하나 방법이 있다.

@Component("myWasher")

이렇게 직접 이름을 지정할 수도 있다.

그러면 Bean 이름은 myWasher가 된다.

 

@Bean도 마찬가지다.

@Bean
public SWasher sWasher() {
    return new SWasher();
}

이 경우 Bean 이름은 메서드 이름을 따라간다.

sWasher

그래서 @Qualifier("sWasher")로 맞춰야 한다.

 

정리하면 이렇게 된다.

@Autowired
타입 기준으로 Bean을 찾는다
@Qualifier
이름 기준으로 Bean을 선택한다

그래서 같은 타입이 여러 개일 때는 반드시 선택 기준이 필요하다.

 

여기서 한 가지 더 알아두면 좋은 것이 있다!!

@Primary는 여러 Bean 중에서 기본으로 사용할 Bean을 지정하는 방식이다.

@Component
@Primary
public class SWasher implements Washer {
}

이렇게 하면 Washer 타입이 여러 개 있어도,
기본적으로 SWasher가 먼저 선택된다.

 

이 상태에서는 @Qualifier 없이도 동작한다.

하지만 특정 상황에서 다른 Bean을 쓰고 싶다면
그때는 @Qualifier를 같이 사용하면 된다.

1. 타입으로 후보 찾기
2. @Primary 있으면 우선 선택
3. @Qualifier 있으면 정확하게 선택

그래서 실무에서는 이렇게 사용한다.

기본 Bean은 @Primary
특정 상황은 @Qualifier

마지막으로 한 줄로 정리하면 이렇다.

@Autowired는 타입으로 찾고
@Qualifier는 이름으로 고른다