예시를 들어 Food는 인터페이스로, Chicken, Pizza는 클래스로 각각 존재한다고 생각해보자.
Food에 eat이라는 메서드가 존재하며 Chicken이랑 Pizza에 둘다 eat()이라는 메소드를 오버라이딩하고 있다고 했을 때 테스트파일에서 @Autowired를 사용하여 Food객체를 만든다면 오류가 뜰것이다..

오류가 난 것을 읽지 않아도 어느 빈을 가지고 오는지를 알 수 없어 난다는 것을 알겠지만, 해당 오류를 보면 Food 타입의 Bean 객체가 하나이상 있습니다 라고 알려주고 있다.
이를 해결하는 방법을 알아보자
@SpringBootTest
public class BeanTest {
@Autowired
Food pizza;
@Autowired
Food chicken;
}
이처럼 Bean의 이름을 정확하게 명시해주면 해결할 수 있다.
@Component
@Primary
public class Chicken implements Food {
@Override
public void eat() {
System.out.println("치킨을 먹습니다.");
}
}
이런식으로 기본으로 사용할 클래스 위에 Primary 애너테이션을 추가하면
@SpringBootTest
public class BeanTest {
@Autowired
Food food;
}
오류가 났었던 이 코드에서 자동으로 chicken을 가져와서 사용할 수 있게 된다.
@Component
@Qualifier("pizza")
public class Pizza implements Food {
@Override
public void eat() {
System.out.println("피자를 먹습니다.");
}
}
Pizza 클래스에 @Qualifier("pizza")를 추가하고,
@SpringBootTest
public class BeanTest {
@Autowired
@Qualifier("pizza")
Food food;
}
주입하고자하는 필드에도 해당 코드를 추가해주면 원하는 Bean 객체가 주입된다.
위에서 했던 방식대로 같은 타입의 Bean들에 Qualifier과 Primary가 동시에 적용되어있다면 Qualifier의 우선순위가 더 높다.
하지만 Qualifier는 적용하기 위해서는 주입 받고자하는 곳에 해당 Qualifier를 반드시 추가해야한다.
따라서 같은 타입의 Bean이 여러개 있을 때에는 범용적으로 사용되는 Bean 객체에는 Primary를, 지엽적으로 사용되는 Bean 객체에는 Qualifier를 사용하는 것이 좋다.