코드 그라데이션
스프링 빈 조회 (1) - 기본 / 동일한 타입이 둘 이상인 경우 본문
Case 1) 조회 - 기본
스프링 컨테이너에서 스프링 빈을 찾는 가장 기본적인 조회 방법
- `ac.getBean(빈이름, 타입)`
- `ac.getBean(타입)`
조회 대상 스프링 빈이 없으면 예외 발생
=> `NoSuchBeanDefinitionException: No bean named 'xxxxx' available
ApplicationContextBasicFindTest
package inflearn.spring_core.beanfind;
import inflearn.spring_core.config.AppConfig;
import inflearn.spring_core.member.MemberService;
import inflearn.spring_core.member.MemberServiceImpl;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
class ApplicationContextBasicFindTest {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
/**
* "memberService" 이름
* MemberService.class 타입
*/
@Test
@DisplayName("빈 이름으로 조회")
void findBeanByName() {
MemberService memberService = ac.getBean("memberService", MemberService.class);
assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
}
@Test
@DisplayName("이름 없이 타입만으로 조회")
void findBeanByType() {
MemberService memberService = ac.getBean(MemberService.class); // 타입만
assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
}
@Test
@DisplayName("구체 타입으로 조회")
void findBeanByName2() {
MemberServiceImpl memberService = ac.getBean("memberService", MemberServiceImpl.class);
assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
}
@Test
@DisplayName("빈 이름으로 조회X")
void findBeanByNameX() {
//ac.getBean("xxxxx", MemberService.class);
Assertions.assertThrows(NoSuchBeanDefinitionException.class,
() -> ac.getBean("xxxxx", MemberService.class));
// xxxxx 이런 이름의 빈이 지금 없다.
}
}
System.out.println("memberService = " + memberService );
System.out.println("memberService.getClass() = " + memberService.getClass());
이렇게 찍어보면 정상적으로 출력됨(존재함)을 확인할 수 있으니 이 부분은 생략하고 작성.
구체 타입으로 조히하면 변경 시 유연성이 떨어진다.
스프링 빈 조회 - 동일한 타입이 둘 이상
- 타입으로 조회시 같은 타입의 스프링 빈이 둘 이상이면 오류가 발생한다. 이때는 빈 이름을 지정하자.
- `ac.getBeansOfType()` 을 사용하면 해당 타입의 모든 빈을 조회할 수 있다.
ApplicationContextSameBeanFindTest
먼저
// 테스트 코드용 static 클래스 생성
@Configuration
static class SameBeanConfig {
@Bean
public MemberRepository memberRepository1() {
return new MemoryMemberRepository();
}
@Bean
public MemberRepository memberRepository2() {
return new MemoryMemberRepository();
}
}
첫 번째 테스트 메서드
@Test
@DisplayName("타입으로 조회 시 같은 타입이 둘 이상 있으면, 중복 오류가 발생한다")
void findBeanByTypeDuplicate() {
MemberRepository bean = ac.getBean(MemberRepository.class);
}
이거 실행을 돌리면
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'inflearn.spring_core.member.MemberRepository' available: expected single matching bean but found 2: memberRepository1,memberRepository2
이런 에러 메시지가 나온다.
2개인데, 뭘 택해야 하는지를 모른다.
테스트 성공하도록 바꾸려면
@Test
@DisplayName("타입으로 조회 시 같은 타입이 둘 이상 있으면, 중복 오류가 발생한다")
void findBeanByTypeDuplicate() {
// MemberRepository bean = ac.getBean(MemberRepository.class);
assertThrows(NoUniqueBeanDefinitionException.class,
() -> ac.getBean(MemberRepository.class));
}
다음 메서드
@Test
@DisplayName("타입으로 조회 시 같은 타입이 둘 이상 있으면, 빈 이름을 지정하면 된다")
void findBeanByName() {
MemberRepository memberRepository = ac.getBean("memberRepository1", MemberRepository.class);
assertThat(memberRepository).isInstanceOf(MemberRepository.class);
// "memberRepository1" 라고 이름 적어뒀음.
}
이름 지정하면 문제 없이 찾을 수 있음.
다음 메서드
@Test
@DisplayName("특정 타입을 모두 조회하기")
void findAllBeanByType() {
Map<String, MemberRepository> beansOfType = ac.getBeansOfType(MemberRepository.class);
for (String key : beansOfType.keySet()) {
System.out.println("key = " + key + " value = " + beansOfType.get(key));
}
System.out.println("beansOfType = " + beansOfType);
assertThat(beansOfType.size()).isEqualTo(2);
}
이렇게 다 조회하면 Map으로 나온다고 한다.
실행 결과
728x90
'Spring > 핵심 원리 구현' 카테고리의 다른 글
BeanFactory와 ApplicationContext (0) | 2024.01.23 |
---|---|
스프링 빈 조회 (2) 상속 관계 (1) | 2024.01.22 |
컨테이너에 등록된 모든 빈 조회 (0) | 2024.01.21 |
스프링 컨테이너 생성 (0) | 2024.01.21 |
이제! 스프링으로 전환하기 (0) | 2024.01.20 |
Comments