Spring
getBean() 메서드 사용과 Bean 관련 Exception 정리
NoSuchBeanDefinitionException: No bean named 'versionPrint2' available
NoSuchBeanDefinitionException: No qualifying bean of type 'spring.MemberPrinter' available
BeanNotOfRequiredTypeException
getBean() 메서드 사용과 Bean관련 Exception 정리
앞에서 Bean 객체를 구할 때에는 getBean()메서드를 이용했다. (혹은 Autowired를 통해 자동으로 빈 객체를 받아왔다.) Autowired를 사용해도 내부적으로 Bean 객체를 호출하며 아래와 같이 NoSuchBeanDefinitionException 같은 것을 볼 수 있는데 왜 이런 문제가 발생하는지 알아보자.
VersionPrinter versionPrinter = ctx.getBean("versionPrinter", VersionPrinter.class)
위와 같이 getBean메서드를 이용하여 빈 객체를 받아 올 수 있는데 메서드의 첫 번째 인자는 빈의 이름이고, 두 번째 인자는 빈의 타입이다. 이 때 getBean() 메서드를 호출할 때 존재하지 않는 빈 이름을 사용하면 익셉션이 발생한다. 예를 들어 "versionPrinter"를 가져와야 하는데 "versionPrinter2"로 잘못 작성했을 경우, 아래와 같은 Exception을 볼 수 있다.
Exception in thread "main"
org.springframework.beans.factory.NoSuchBeanDefinitionException:
No bean named 'versionPrinter2' available
NoSuchBeanDefinitionException: No bean named 'versionPrint2' available 의 내용을 해석하자면, versionPrinter2인 이름의 빈이 사용 가능하지 않다는 의미인데, 이를 통해 getBean() 메서드에 전달된 빈의 이름이 잘못 되었음을 알 수 있다.
[ ]
만약 빈의 실제 타입과 getBean() 메서드에 지정한 타입이 다르면 어떻게 될까? 이름이 listPrinter인 빈 타입이 MemberListPrinter인데 다음이 getBean() 메서드에 VersionPrinter 클래스를 전달했다고 하자.
VersionPrinter versionPrinter = ctx.getBean("listPrinter", VersionPrinter.class);
이 경우 발생하는 익셉션은 다음과 같다.
Exception in thread "main"
org.springframework.beans.factory.BeanNotOfRequiredTypeException:
Bean named 'listPrinter' is excepted to be of type 'spring.VersionPrinter'
but was actually of type 'spring.MemberListPrinter'
BeanNotOfRequiredTypeException: Bean named 'listPrinter' is excepted to be of typeBeanNotOfRequiredTypeException: Bean named 'listPrinter' is excepted to be of type 'spring.VersionPrinter' but was actually of type 'spring.MemberListPrinter'
에러 메세지는 'listPrinter'의 타입으로 VersionPrinter 타입을 기대했는데 실제 타입은 MemberListPrinter라는 사실을 알려주고 있다.
다음과 같이 빈 이름을 지정하지 않고 타입만으로 빈을 구할 수도 있다.
VersionPrinter versionPrinter = ctx.getBean(MemberPrinter.class)
이 때 해당 타입의 빈 객체가 한 개만 존재하면 해당 빈을 구해서 리턴한다. 해당 타입의 빈 객체가 존재하지 않으면 다음과 같은 익셉션이 발생한다.
Exception in thread "main"
org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type 'spring.MemberPrinter' available
NoSuchBeanDefinitionException: No qualifying bean of type 'spring.MemberPrinter' available
같은 타입의 빈 객체가 두 개 이상 존재할 수도 있다. 예를 들어 설정 클래스에 다음과 같이 타입이 VersionPrinter인 빈을 두 개 설정했다고 하자.
@Configuration
public class AppCtx {
... // 생략
@Bean
public VersionPrinter versionPrinter() {
VersionPrinter versionPrinter = new VersionPrinter();
versionPrinter.setMajorVersion(5);
versionPrinter.setMinorVersion(0);
return versionPrinter;
}
@Bean
public VersionPrinter oldVersionPrinter() {
VersionPrinter versionPrinter = new VersionPrinter();
versionPrinter.setMajorVersion(4);
versionPrinter.setMinorVersion(3);
return versionPrinter;
}
}
이 경우 ctx.getBean(VersionPrinter.class) 메서드를 실행하면 다음과 같은 익셉션이 발생한다.
Exception in thread "main"
ord.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type 'spring.VersionPrinter' available:
expected single matching bean but found 2: versionPrinter.oldVersionPrinter
이 익셉션은 VersionPrinter 타입의 빈을 구하려 하는데, 해당 타입의 빈이 한 개가 아니고 두 개 (이름이 versionPrinter인 빈과 oldVersionPrinter인 빈) 존재한다는 내용을 보여준다.
관련글
'개발 > Spring' 카테고리의 다른 글
[Spring 프로젝트] Swagger 연동하기 (0) | 2020.11.11 |
---|---|
[Spring 프로젝트] Spring AOP 로거 개발 가이드 (0) | 2020.11.09 |
[Spring DI] 3. Spring에서 두 개 이상의 설정 파일 사용하기 (0) | 2020.11.08 |
[Spring DI] 2. Spring DI 설정 (0) | 2020.11.08 |
[Spring DI] 1. 스프링 DI(Dependency Injection)란? (0) | 2020.11.08 |