@ComponentScan 을 통해 빈 등록을 위한 컴포넌트 스캔을 조작할 수 있다.
basePackages 옵션을 통해 컴포넌트 스캔을 시작할 패키지의 위치를 직접 설정할 수 있으나 디폴트는 일단 @Component 가 있는 클래스가 속한 패키지를 시작으로 그 하위를 모두 스캔한다.
일반적이고 바람직한 방식은 스캔 시작 패키지를 따로 지정하기 보다는 설정 정보 클래스(AppConfig)를 프로젝트 최상단에 두는 것이다.
프로젝트의 구조가 다음과 같다면,
com.hello
com.hello.service
com.hello.repository
AppConfig를 com.hello 하위에 만들고 @ComponentScan을 다는 것이다. 그럼 service, repository 모든 패키지를 스캔할 수 있다.
컴포넌트 스캔을 시작하면 스캔 범위에 해당하는 모든 클래스를 검사하여 @Component 가 붙은 모든 클래스의 빈을 등록한다.
(@Configuration, @Controller, @Service, @Repository 등은 모두 내부에 @Component를 포함하고 있다.)
스프링 부트를 사용할 때는 @SpringBootApplication 을 프로젝트 시작 루트 위치에 두는 것이 일반적이다.
(@SpringBootApplication은 내부적으로 @Component를 포함한다.)
또한 굳이 AppConfig 내부에서 @Bean을 통해 의존성 주입을 수동으로 해주지 않아도 @Autowired를 통해 자동으로 의존성 주입을 해줄 수 있다.
@Component
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberServiceImpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
이렇게 생성자에 @Autowired를 달아 의존성 생성자 주입을 자동으로 해줄 수 있다.
(@Autowired 를 찾으면 해당 함수의 파라미터의 타입으로 주입할 빈을 찾는다.)
(필드주입에도 @Autowired 사용 가능함)
이때, 만약 등록할 빈의 클래스에 @Component가 붙어있지 않거나 스캔의 범위에서 벗어나있어 빈 등록이 되지 않았을 경우 에러가 발생한다.
또한, 해당 빈의 타입으로 여러 가지 빈이 존재할 수 있는데 이 경우에는 @Qualifier 를 통해 어떤 타입의 빈을 주입할 것인지 명시할 수 있다.
@Component
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberServiceImpl(@Qualifier("memory") MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
.
.
.
@Repository("memory")
public class MemoryMemberRepository implements MemberRepository {
...
}
의존성 주입에서 우선순위를 두고 싶은 빈의 이름을 @Qualifier에 담아 어노테이션을 달아놓으면 해당 빈을 우선적으로 찾아 주입한다.
(codeung.tistory.com/116 에서 좀 더 자세히 설명)
'김영한님 스프링 강의 정리 > 핵심원리 기본편' 카테고리의 다른 글
의존성 주입 @Autowired, 옵션 처리 설정 (0) | 2021.01.11 |
---|---|
빈 이름 중복에 의한 충돌 (0) | 2021.01.10 |
@Configuration과 싱글톤 패턴 (0) | 2021.01.08 |
싱글톤 컨테이너 (0) | 2021.01.08 |
컨테이너에 등록된 Bean 모두 조회 (0) | 2021.01.07 |