티스토리 뷰
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가 등록된 빈을 찾을 때에는 다음과 같은 매칭 규칙으로 빈을 조회한다.
- 주입받고자하는 타입으로 매칭을 시도한다.
- 타입이 여러 개면 필드 또는 파라미터 이름으로 매칭을 시도한다.
하지만 빈의 이름이 충돌되어 빈 이름만으로 해결이 불가능한 경우 또는 빈에 추가 구분자나 우선순위를 부여하고 싶은 경우에 @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;
}
- 해당 @Qualifier가 붙은 빈을 조회한다.
- @Qualifier가 붙은 빈을 못찾으면 필드 또는 파라미터 이름으로 매칭을 시도한다.
- 그래도 찾지 못하면 NoSuchBeanDefinitionException 이 발생한다.
물론 빈을 찾고자하는 경우에 @Qualifier를 붙이지 않아도 정상적으로 작동한다. 하지만 이렇게 하면 유지보수 하면서 헷갈릴 수 있으므로 빈을 생성하는 곳과 찾는 곳 모두에 @Qualifier를 붙여주도록 하자.
[ @Primiary - 빈의 우선순위 부여 ]
여러 타입의 빈이 존재할 때, 특정 빈을 우선적으로 주입하도록 하고 싶다면 @Primary 어노테이션을 사용할 수 있다. Spring이 타입으로 빈을 찾다가 Primary가 붙어있는 빈을 발견하면, 바로 해당 빈을 주입시킨다. 즉, @Primary는 여러 개의 빈들 중에서 우선순위를 부여하는 방법이다.
@Primary
@Bean
public DiscountPolicy fixDiscountPolicy() {
return new FixDiscountPolicy();
}
만약 Primary와 Qualifier 모두 등록이 되어있다면 이름을 직접 지정해주는 Qualifier가 우선순위를 갖는다.
[ 빈 등록 출동 발생 ]
하지만 위와 같이 설정해주지 않아 빈 등록 시에 충돌이 발생한다면 Spring에서는 다음과 같이 처리가 된다.
- 자동 빈 vs 자동 빈: 빈 이름 중복 에러 발생
- 수동 빈 vs 자동 빈: 과거에는 수동빈이 자동 빈을 덮어버렸음 But 최근에는 에러를 발생시키도록 변경됨
출처: https://mangkyu.tistory.com/148?category=761302 [MangKyu's Diary]
'Spring' 카테고리의 다른 글
[망나니 개발자] 생성자 주입을 사용해야 하는 이유 (0) | 2021.06.08 |
---|---|
[망나니 개발자] 빈(Bean)의 생성과 소멸에 대한 관리(초기화와 소멸자) (0) | 2021.06.08 |
[망나니 개발자] 의존성 주입(Dependency Injection, DI)을 지원하는 이유 (0) | 2021.06.08 |
[망나니 개발자] 애플리케이션 컨텍스트(Application Context)와 싱글톤(Singleton) (0) | 2021.06.08 |
[망나니 개발자] Spring 프레임워크와 롬봄(Lombok)의 결합, 생성자 주입 (0) | 2021.06.08 |