1. 개요
이 예제에서는 @Qualifier 어노테이션이 우리에게 어떤 도움을 줄 수 있는지 , 어떤 문제를 해결하는지, 어떻게 사용하는지 살펴보겠습니다.
또한 @Primary 어노테이션과 이름으로 자동 연결 하는 것과 어떻게 다른지 설명합니다 .
2. 명확성을 위한 Autowire의 필요성
@Autowired 어노테이션은 명시 적으로 Spring에 의존성을 주입 할 필요가 만드는 좋은 방법입니다. 유용하기는 하지만 이 어노테이션만으로는 Spring이 주입할 빈을 이해하기에 충분하지 않은 사용 사례가 있습니다.
기본적으로 Spring은 유형별로 자동 연결된 항목을 해결합니다.
컨테이너에서 동일한 유형의 두 개 이상의 빈을 사용할 수 있는 경우 프레임워크는 NoUniqueBeanDefinitionException 을 throw하여 자동 연결 에 둘 이상의 빈을 사용할 수 있음을 나타냅니다.
Spring이 주어진 인스턴스에서 빈 협력자로 주입할 수 있는 두 가지 후보가 존재하는 상황을 상상해보자.
@Component("fooFormatter")
public class FooFormatter implements Formatter {
public String format() {
return "foo";
}
}
@Component("barFormatter")
public class BarFormatter implements Formatter {
public String format() {
return "bar";
}
}
@Component
public class FooService {
@Autowired
private Formatter formatter;
}
FooService 를 컨텍스트 에 로드하려고 하면 Spring 프레임워크는 NoUniqueBeanDefinitionException 을 던질 것 입니다 . 이것은 Spring이 어떤 bean을 주입할지 모르기 때문이다 . 이 문제를 방지하기 위해 몇 가지 솔루션이 있습니다. @Qualifier의 어노테이션 그들 중 하나입니다.
3. @Qualifier 어노테이션
@Qualifier 어노테이션 을 사용하면 어떤 빈을 주입해야 하는지 문제를 없앨 수 있습니다 .
사용하려는 빈을 나타내기 위해 @Qualifier 어노테이션을 포함하여 문제를 해결하는 방법을 보기 위해 이전 예제를 다시 살펴보겠습니다 .
public class FooService {
@Autowired
@Qualifier("fooFormatter")
private Formatter formatter;
}
포함함으로써 @Qualifier에 우리가 함께 사용할 특정 구현의 이름으로, 어노테이션,이 예에서 푸, Spring이 동일한 유형의 여러 Bean을 발견하면 우리는 모호함을 피할 수 있습니다.
사용할 한정자 이름이 @Component 어노테이션에 선언된 이름이라는 점을 고려해야 합니다 .
동일한 효과를 얻기 위해 @Component 어노테이션에 이름을 지정하는 대신 Formatter 구현 클래스 에서 @Qualifier 어노테이션을 사용할 수도 있습니다 .
@Component
@Qualifier("fooFormatter")
public class FooFormatter implements Formatter {
//...
}
@Component
@Qualifier("barFormatter")
public class BarFormatter implements Formatter {
//...
}
4. @Qualifier 대 @Primary
의존성 주입과 관련하여 모호성이 존재할 때 주입할 빈을 결정하는 데 사용할 수 있는 @Primary 라는 또 다른 어노테이션이 있습니다 .
이 어노테이션은 동일한 유형의 여러 Bean이 있는 경우 기본 설정을 정의합니다 . 달리 명시되지 않는 한 @Primary 어노테이션 과 관련된 빈이 사용됩니다.
예를 들어 보겠습니다.
@Configuration
public class Config {
@Bean
public Employee johnEmployee() {
return new Employee("John");
}
@Bean
@Primary
public Employee tonyEmployee() {
return new Employee("Tony");
}
}
이 예에서 두 메서드는 동일한 Employee 유형을 반환합니다 . Spring이 주입할 빈은 tonyEmployee 메소드에 의해 반환된 것이다 . @Primary 어노테이션 이 포함되어 있기 때문 입니다. 이 어노테이션은 기본적으로 특정 유형의 빈을 주입해야 할 때 유용합니다 .
어떤 주입 지점에서 다른 빈이 필요한 경우 구체적으로 표시해야 합니다. @Qualifier 어노테이션 을 통해 이를 수행할 수 있습니다 . 예를 들어, @Qualifier 어노테이션 을 사용하여 johnEmployee 메소드에서 반환된 빈을 사용하도록 지정할 수 있습니다.
있다는 지적이의 가치가 양쪽 경우 @Qualifier 와 @primary 어노테이션이 존재하는 다음 @Qualifier의 어노테이션이 우선해야합니다. 기본적으로 @Primary 는 기본값을 정의하는 반면 @Qualifier 는 매우 구체적입니다.
이번에는 초기 예제 를 사용하여 @Primary 어노테이션 을 사용하는 다른 방법을 살펴보겠습니다 .
@Component
@Primary
public class FooFormatter implements Formatter {
//...
}
@Component
public class BarFormatter implements Formatter {
//...
}
이 경우 @Primary 어노테이션은 구현 클래스 중 하나에 배치되고 시나리오를 명확하게 합니다.
5. @Qualifier vs Autowiring by Name
autowiring할 때 여러 bean 사이를 결정하는 또 다른 방법은 주입할 필드의 이름을 사용하는 것입니다. 이것은 Spring에 대한 다른 힌트가 없는 경우의 기본값입니다 . 초기 예제를 기반으로 몇 가지 코드를 살펴보겠습니다.
public class FooService {
@Autowired
private Formatter fooFormatter;
}
이 경우 Spring은 필드 이름이 해당 빈 에 대한 @Component 어노테이션 에서 사용한 값과 일치하기 때문에 주입할 빈이 FooFormatter 인지 결정할 것입니다 .
6. 결론
이 기사에서 우리는 주입할 빈을 명확하게 해야 하는 시나리오를 설명했습니다. 특히 @Qualifier 어노테이션 을 조사하고 어떤 빈을 사용해야 하는지 결정하는 다른 유사한 방법과 비교했습니다.