티스토리 뷰
Spring Boot로 Bean을 생성시 Bean이 생성되지 않고 다음과 비슷 예외메세지가 본 적이 있을 것이다.
NoSuchBeanDefinitionException: No qualifying bean of type 'com.kjh.component.StudyComponent'
available: expected at least 1 bean which qualifies as autowire candidate.
Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
StudyComponent 타입의 Bean을 찾지못했다는 메세지인데 왜 이런 메세지가 나오는지 예제코드와 함꼐 확인해보자.
프로젝트 구조
현재 프로젝트 구조는 다음과 같다. com.kjh.study 패키지에 애플리케이션을 구동할 main메서드가 있고
com.kjh.component 패키지에는 StudyComponent 라는 클래스가 있으며 Bean으로 등록하기 위해 @Component 어노테이션 주석이 선언되있다.
테스트 (1)
@Autowired 어노테이션으로 생성한 Bean을 주입받기위해 테스트를 돌려보았지만 Bean을 찾을 수 없다는 예외가 발생됐다.
원인
원인은 @SpringBootApplication 어노테이션 내부에서 찾아볼 수 있었다. 바로 @EnableAutoConfiguration 어노테이션인데 이 어노테이션의 역할은 Spring Application Context구동에 필요한 설정들을 자동으로 활성화하여 그 대상들을 Bean으로 등록하게 된다.
@EnableAutoConfiguration의 자동설정 대상이 되는 클래스들은 jar파일 목록들중에 spring-boot-autoconfigure-version명.jar 파일을 확인하면 META-INF폴더에 spring.factories 라는 폴더가 있는데 여기에 적혀있는 모든 클래스들이 자동설정 대상이 된다
@EnableAutoConfiguration 어노테이션 내부에 적힌 설명중 다음과 같이 적힌걸 확인할 수 있다.
맨 아랫줄을 읽게되면 @SpringBootApplication 어노테이션 주석이 선언된 클래스를 root package가 되며
root package를 기준으로 하위에 존재하는 모든 package들 중에서 @Component 어노테이션이 선언된 클래스 또는 Config 자바파일생성시 이 파일을 Spring에게 알리는 @Configuration 어노테이션이 선언된 클래스들 을 Bean으로 등록한다.
패키지 구조 변경
기존에 존재한 com.kjh.component 패키지를 @SpringBootApplication 어노테이션 주석이 선언된 패키지 하위로 변경하였다. 그리고 이제 테스트를 해보자
테스트 (2)
정상적으로 Bean 주입이 된 걸 볼 수있다.
@ComponentScan
만일 등록하고자 하는 Bean이 root package 범위밖에 존재하다면 @ComponentScan어노테이션으로 해당패키지명을 지정해줄 수 있다.
테스트 (3)