스프링 컨테이너의 기본적인 스프링 빈 조회 방법
- ac.getBean(빈이름, 타입)
- ac.getBean(타입)
- 조회 대상 스프링 빈이 없으면 오류 발생
- NoSuchBeanDefinitionException: No bean named ‘xxxx’ available
예제 코드
package hello.core.beanfind;
import hello.core.AppConfig;
import hello.core.member.MemberService;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class ApplicationContextBasicFindTest {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
@Test
@DisplayName("빈 이름으로 조회")
void findBeanByName() {
MemberService memberService = ac.getBean("memberService", MemberService.class);
System.out.println("memberService = " + memberService);
System.out.println("memberService.getClass() = " + memberService.getClass());
}
}
- 출력 결과
- memberService = hello.core.member.MemberServiceImpl@37c7595
- memberService.getClass() = class hello.core.member.MemberServiceImpl
빈 이름으로 조회 검증
package hello.core.beanfind;
import hello.core.AppConfig;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import static org.assertj.core.api.Assertions.*;
public class ApplicationContextBasicFindTest {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
@Test
@DisplayName("빈 이름으로 조회")
void findBeanByName() {
MemberService memberService = ac.getBean("memberService", MemberService.class);
assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
}
}
- memberService는 MemberServiceImpl의 인스턴스
- AppConfig에서 memberService 메소드는 MemberServiceImpl 객체를 new 하여 리턴
- return new MemberServiceImpl(*memberRepository*());
이름 없이 타입으로만 조회 추가
package hello.core.beanfind;
import hello.core.AppConfig;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import static org.assertj.core.api.Assertions.*;
public class ApplicationContextBasicFindTest {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.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);
}
}
- 테스트 통과
구체 타입으로 조회 추가
package hello.core.beanfind;
import hello.core.AppConfig;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import static org.assertj.core.api.Assertions.*;
public class ApplicationContextBasicFindTest {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.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() {
MemberService memberService = ac.getBean("memberService", MemberServiceImpl.class);
assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
}
}
- 빈 이름으로 조회 시 인터페이스인 MemberService가 아닌, 구체 클래스인 MemberServiceImpl로 타입을 넣어도 정상 조회 가능
- AppConfig에서 memberService의 반환 타입이 MemberService라도 MemberServiceImpl로 타입을 넣을 수 있음
- 하지만 이 같이 구체 클래스를 타입으로 넣는 것은 좋지 않은 방법(역할과 구현의 분리, 역할에 의존)
- 유연성이 떨어지지만, 가끔 필요할 때가 있음
빈 이름으로 조회X 추가
package hello.core.beanfind;
import hello.core.AppConfig;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import org.assertj.core.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.*;
import static org.junit.jupiter.api.Assertions.*;
public class ApplicationContextBasicFindTest {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.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() {
MemberService memberService = ac.getBean("memberService", MemberServiceImpl.class);
assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
}
@Test
@DisplayName("빈 이름으로 조회X")
void findBeanByNameX() {
// ac.getBean("xxxxx", MemberService.class);
// NoSuchBeanDefinitionException이 발생해야 테스트 성공
assertThrows(NoSuchBeanDefinitionException.class,
() -> ac.getBean("xxxxx", MemberService.class));
}
}
- NoSuchBeanDefinitionException이 발생해야 테스트 성공
- assertThrows는 static import 한 상태
- org.junit.jupiter.api.Assertions을 사용(assertThat은 assertj)
- import static org.junit.jupiter.api.Assertions.*;
※ 본 게시글은 인프런의 스프링 핵심 원리 - 기본편(김영한)을 수강하고 정리한 내용입니다.
'Study > Spring' 카테고리의 다른 글
[스프링 핵심 원리 - 기본편] 스프링 컨테이너와 스프링 빈(스프링 빈 조회 - 상속관계★) (0) | 2022.12.26 |
---|---|
[스프링 핵심 원리 - 기본편] 스프링 컨테이너와 스프링 빈(스프링 빈 조회 - 동일한 타입이 둘 이상) (0) | 2022.12.25 |
[스프링 핵심 원리 - 기본편] 스프링 컨테이너와 스프링 빈(컨테이너에 등록된 모든 빈 조회) (0) | 2022.12.23 |
[스프링 핵심 원리 - 기본편] 스프링 컨테이너와 스프링 빈(스프링 컨테이너 생성) (0) | 2022.12.21 |
[스프링 핵심 원리 - 기본편] 스프링 핵심 원리 이해2 - 객체 지향 원리 적용(스프링으로 전환하기) (0) | 2022.12.17 |