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 어노테이션에 선언된 이름이라는 점을 고려해야 합니다 .

Note that we could have also used the @Qualifier annotation on the Formatter implementing classes, instead of specifying the names in their @Component annotations, to obtain the same effect:

@Component
@Qualifier("fooFormatter")
public class FooFormatter implements Formatter {
    //...
}

@Component
@Qualifier("barFormatter")
public class BarFormatter implements Formatter {
    //...
}

4. @Qualifier vs @Primary

There's another annotation called @Primary that we can use to decide which bean to inject when ambiguity is present regarding dependency injection.

This annotation defines a preference when multiple beans of the same type are present. The bean associated with the @Primary annotation will be used unless otherwise indicated.

Let's see an example:

@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 어노테이션 을 조사하고 어떤 빈을 사용해야 하는지 결정하는 다른 유사한 방법과 비교했습니다.

평소와 같이 이 기사의 전체 코드는 GitHub 에서 사용할 수 있습니다 .

Generic footer banner