[Spring] @Autowired 빈 탐색 전략과 @Qualifier, @Primary
2022. 4. 8. 23:34
반응형
[@Autowired 빈 탐색 전략과 @Qualifier, @Primary]
1. 빈(Bean) 등록과 조회 규칙
[ 빈 등록 ]
Spring은 기본적으로 메서드의 이름을 Bean의 이름으로 사용한다. 하지만 개발자가 직접 빈의 이름을 부여할 수도 있다.
@Bean
public DiscountPolicy fixDiscountPolicy() {
return new FixDiscountPolicy();
}
@Bean("fixDiscountPolicy")
public DiscountPolicy fixDiscountPolicy() {
return new FixDiscountPolicy();
}
[ 빈 조회 규칙 전략 ]
@Autowired가 등록된 빈을 찾을 때에는 다음과 같은 매칭 규칙으로 빈을 조회한다.
- 주고받고자 하는 타입으로 매칭을 시도한다.
- 타입이 여러 개면 필드 또는 파라미터 이름으로 매칭을 시도한다.
하지만 빈의 이름이 충돌되어 빈 이름만으로 해결이 불가능한 경우나 빈에 추가 구분자나 우선순위를 부여하고 싶은 경우에 @Qualifier나 @Primary 어노테이션을 이용해 편리하게 해결할 수 있다.
추가로 Spring은 @Resource라는 어노테이션도 제공하고 있다. @Resource는 @Autowired와 달리 필드 이름으로 빈을 찾는다.
- @Autowired: 필드 타입을 기준으로 빈을 찾음
- @Resource: 필드 이름을 기준으로 빈을 찾음
2. @Qualifier와 @Primary
[ @Qualifier - 빈의 Alias(구분자) ]
빈의 이름만으로 부족하고, 추가적인 정보가 필요할 수 있다. 그런 상황에서 @Qualifier 어노테이션을 통해 빈에 추가 구분자를 붙여줄 수 있다.
@Qualifier("mainDiscountPolicy")
@Bean
public DiscountPolicy fixDiscountPolicy() {
return new FixDiscountPolicy();
}
다음과 같이 빈을 찾고자하는 경우에 @Qualifier 어노테이션을 부여하여 빈을 찾도록 할 수 있다.
public class DiscountServie {
private final DiscountPolicy discountPolicy;
@Autowired
public DiscountService(@Qualifier("mainDiscountPolicy") DiscountPolicy discountPolicy) {
this.discountPolicy = discountPolicy;
}
}
- 해당 @Qualifier가 붙은 빈을 조회한다.
- @Qualifier가 붙은 빈을 찾지 못하면 필드명 또는 파라미터명으로 매칭을 시도한다.
- 그래도 찾지못하면 NoSuchBeanDefinitionException 이 발생한다.
[ @Primary - 빈의 우선순위 부여 ]
여러 타입의 빈이 존재할 때, 특정 빈을 우선적으로 주입하도록 하고 싶다면 @Primary 어노테이션을 사용할 수 있다. Spring이 타입으로 비을 찾다가 Primary가 붙어있는 빈을 발견하면, 바로 해당 빈을 주입시킨다. 즉, @Primary는 여러 개의 빈들 중에 우선순위를 부여하는 방법이다.
@Primary
@Bean
public DiscountPolicy fixDiscountPolicy() {
return new FixDiscountPolicy();
}
만약 @Primary와 @Qualifier 모두 등록되어있다면 Qualifier가 우선순위를 갖는다.
[ 빈 충돌 발생 ]
빈 등록 시, 충돌이 발생한다면
- 자동 빈 등록 vs 자동 빈 등록: 빈 이름 중복 에러가 발생한다.
- 수동 빈 등록 vs 자동 빈 등록: 과거에는 수동 빈이 우선순위였지만 최근에는 에러가 발생한다.
728x90
반응형
'web > Spring' 카테고리의 다른 글
[Spring] 빈 생명주기 콜백 - @PostConstruct, @PreDestroy (2) | 2022.04.12 |
---|---|
[Spring JPA] 일반 Join과 Fetch Join의 차이 (0) | 2022.04.11 |
[Spring] 엔티티(Entity) 또는 도메인 객체(Domain Object)와 DTO를 분리해야 하는 이유 (0) | 2022.04.06 |
[Spring Data JPA] EntityGraph (0) | 2022.04.04 |
[Spring Boot] 액추에이터 사용하기 (0) | 2022.04.01 |
Written by ner.o
개발자 네로의 개발 일기,
자바를 좋아합니다 !
댓글 개