티스토리 뷰

Spring

[Spring] @Autowired 빈 탐색 전략과 @Qualifier와 @Primary

망나니개발자 2021. 4. 25. 14:26
반응형

1. 빈(Bean) 등록과 조회 규칙


[ 빈(Bean) 등록 ]

Spring은 기본적으로 메소드/클래스의 이름을 Bean의 이름으로 사용한다.

@Bean
public DiscountPolicy fixDiscountPolicy() {
    return new FixDiscountPolicy();
}

@Bean
public DiscountPolicy rateDiscountPolicy() {
    return new RateDiscountPolicy();
}

 

 

하지만 개발자가 직접 빈의 이름을 부여할 수도 있다.

@Bean("fixDiscountPolicy")
public DiscountPolicy fixDiscountPolicy() {
    return new FixDiscountPolicy();
}

@Bean("rateDiscountPolicy")
public DiscountPolicy rateDiscountPolicy() {
    return new RateDiscountPolicy();
}

 

[ 빈(Bean) 조회 규칙(전략) ]

@Autowired가 등록된 빈을 찾을 때에는 다음과 같은 매칭 규칙으로 빈을 조회한다.

  1. 주입받고자하는 타입으로 매칭을 시도한다.
  2. 타입이 여러 개면 필드 또는 파라미터 이름으로 매칭을 시도한다.

 

하지만 빈의 이름이 충돌되어 빈 이름만으로 해결이 불가능한 경우 또는 빈에 추가 구분자나 우선순위를 부여하고 싶은 경우에 @Qualifer나 @Primary 어노테이션을 이용해 편리하게 해결할 수 있다.

추가로 Spring은 자바 표준 어노테이션인 @Resource라는 어노테이션도 기능을 지원하고 있다. @Resource는 @Autowired와 달리 필드 이름으로 빈을 찾는다.

  • @Autowired: 필드 타입을 기준으로 빈을 찾음 
  • @Resource: 필드 이름을 기준으로 빈을 찾음

 

 

 

2. @Qualifier와 @Primary


[ @Qualifier - 빈의 Alias(구분자) ]

빈의 이름만으로 부족하고, 추가적인 정보가 필요할 수 있다. 그런 상황에서 Qualifier 어노테이션을 통해 빈에 추가 구분자(Alias)를 붙여줄 수 있다. (Bean의 이름을 바꾸는 것은 아니다.)

만약 우리가 위의 두 가지 DiscountPolicy 중에서 FixDiscountPolicy를 중점적으로 활용하고 싶다면, 해당 Bean에 mainDiscountPolicy라는 별칭 또는 구분자를 부여해줄 수 있다.

@Qualifier("mainDiscountPolicy")
@Bean
public DiscountPolicy fixDiscountPolicy() {
    return new FixDiscountPolicy();
}

 

 

그러면 다음과 같이 빈을 찾고자 하는 경우에 @Qualifer 어노테이션을 부여하여 빈을 찾도록 할 수 있다.

public DiscountService(@Qualifier("mainDiscountPolicy") fixDiscountPolicy) {
    this.discountPolicy = fixDiscountPolicy;
}

 

  1. 해당 @Qualifier가 붙은 빈을 조회한다.
  2. @Qualifier가 붙은 빈을 못찾으면 필드 또는 파라미터 이름으로 매칭을 시도한다.
  3. 그래도 찾지 못하면 NoSuchBeanDefinitionException 이 발생한다.

 

물론 빈을 찾고자하는 경우에 @Qualifier를 붙이지 않아도 정상적으로 작동한다. 하지만 이렇게 하면 유지보수 하면서 헷갈릴 수 있으므로 빈을 생성하는 곳과 찾는 곳 모두에 @Qualifier를 붙여주도록 하자.

 

 

 

[ @Primiary - 빈의 우선순위 부여 ]

여러 타입의 빈이 존재할 때, 특정 빈을 우선적으로 주입하도록 하고 싶다면 @Primary 어노테이션을 사용할 수 있다. Spring이 타입으로 빈을 찾다가 Primary가 붙어있는 빈을 발견하면, 바로 해당 빈을 주입시킨다. 즉, @Primary는 여러 개의 빈들 중에서 우선순위를 부여하는 방법이다.

@Primary
@Bean
public DiscountPolicy fixDiscountPolicy() {
    return new FixDiscountPolicy();
}

 

 

만약 Primary와 Qualifier 모두 등록이 되어있다면 이름을 직접 지정해주는 Qualifier가 우선순위를 갖는다.

 

 

 

 

[ 빈 등록 출동 발생 ]

하지만 위와 같이 설정해주지 않아 빈 등록 시에 충돌이 발생한다면 Spring에서는 다음과 같이 처리가 된다.

  • 자동 빈 vs 자동 빈: 빈 이름 중복 에러 발생
  • 수동 빈 vs 자동 빈: 과거에는 수동빈이 자동 빈을 덮어버렸음 But 최근에는 에러를 발생시키도록 변경됨
반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG more
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함