티스토리 뷰
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 최근에는 에러를 발생시키도록 변경됨
'Spring' 카테고리의 다른 글
[Spring] 애플리케이션 컨텍스트(Application Context)와 스프링의 싱글톤(Singleton) (2) | 2021.05.09 |
---|---|
[Spring] 의존성 주입(Dependency Injection, DI)이란? 및 Spring이 의존성 주입을 지원하는 이유 (38) | 2021.05.07 |
[Spring] JUnit과 Mockito 기반의 Spring 단위 테스트 코드 작성법 (3/3) (41) | 2021.04.20 |
[SpringBoot] 기존 SpringBoot 프로젝트 실무처럼 리팩토링 하기 (9) | 2021.03.19 |
[Spring] 빈(Bean)의 생성과 소멸에 대한 관리(@PostConstruct초기화와 @PreDestroy소멸자) (0) | 2021.02.02 |