∨ 등록해야할 스프링빈이 엄청 많아지면 @Bean으로 다 등록해주기가 까다로워짐
=> 스프링이 컴포넌트 스캔 기능 제공
이전 : @Configuration에서 @Bean을 통한 수동 bean 등록
- 의존관계가 직접 명시되어있었다.
지금 하는 거 : @ComponentScan을 통한 자동 bean 등록 (즉, @Bean 사용X)
- @Component가 붙은 클래스들을 스캔 -> 스프링빈으로 등록
- 각 빈에 대해 의존관계를 명시하지 않는다
=> 그럼 어떻게 DI 주입?
=> @Autowired가 의존관계를 자동으로 주입해준다.
● 예시
① 컴포넌트 스캔 기능을 이용하기 위해서
@ComponentScan을 붙인 설정정보(@Configuration) AutoAppConfig를 만들었다.
cf. 저 excludeFilters는 그냥.. 이전 실습한 수동 설정정보 빼주려고 붙인 거다.
@Configuration
@ComponentScan(
excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Configuration.class))
public class AutoAppConfig {
}
② 스캔의 대상이 되는 클래스(스프링빈으로 등록할 것)에 @Component를 붙여주었다.
@Component
public class RateDiscountPolicy implements DiscountPolicy{
...
}
@Component
public class MemoryMemberRepository implements MemberRepository{
...
}
@Component
public class MemberServiceImpl implements MemberService{
...
}
@Component
public class OrderServiceImpl implements OrderService{
...
}
③ 의존관계 자동 주입을 위해 @Autowired를 사용했다.
저렇게 생성자에 @Autowired 붙여주면, 필요한 애를 자동으로 찾아와서 주입해준다.
cf) ac.getBean(MemberRepository.class)처럼 찾아오는 원리다.
@Component
public class MemberServiceImpl implements MemberService{
private final MemberRepository memberRepository;
@Autowired
public MemberServiceImpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
....
}
@Component
public class OrderServiceImpl implements OrderService{
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
...
}
● 테스트
public class AutoAppConfigTest {
@Test
void basicScan() {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class);
MemberService memberService = ac.getBean(MemberService.class);
assertThat(memberService).isInstanceOf(MemberService.class);
}
}
로그를 보자.
∨ ClassPathBeanDefinitionScanner <- 요런 애가 보이면서
@Component를 붙였던 스캔대상 클래스들이 대상이 되었다.
16:44:12.363 [main] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [C:\Users\kye33\study\core\build\classes\java\main\hello\core\discount\RateDiscountPolicy.class]
16:44:12.366 [main] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [C:\Users\kye33\study\core\build\classes\java\main\hello\core\member\MemberServiceImpl.class]
16:44:12.368 [main] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [C:\Users\kye33\study\core\build\classes\java\main\hello\core\member\MemoryMemberRepository.class]
16:44:12.370 [main] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [C:\Users\kye33\study\core\build\classes\java\main\hello\core\order\OrderServiceImpl.class]
∨ 그리고 곧.. 오ㅏ우~
싱글톤빈으로 객체가 생성되었고 의존관계까지 주입되었다. (autowiring)
16:44:12.572 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'autoAppConfig'
16:44:12.580 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'rateDiscountPolicy'
16:44:12.582 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'memberServiceImpl'
16:44:12.616 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'memoryMemberRepository'
16:44:12.617 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Autowiring by type from bean name 'memberServiceImpl' via constructor to bean named 'memoryMemberRepository'
16:44:12.621 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'orderServiceImpl'
16:44:12.625 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Autowiring by type from bean name 'orderServiceImpl' via constructor to bean named 'memoryMemberRepository'
16:44:12.625 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Autowiring by type from bean name 'orderServiceImpl' via constructor to bean named 'rateDiscountPolicy'
∨ 스프링빈 이름 기본규칙
: 클래스명 & 맨앞글자는 소문자로 바뀜
∨ @Autowired
: 자동으로 DI
: 기본 조회전략 - (생성자 파라미터에) 명시된 것과 동일타입인 빈을 DI
cf) getBean(MemberRepository.class)와 동일하다고 이해하자
: 생성자가 딱 1개만 있으면 생략가능
'web +a' 카테고리의 다른 글
생성자 주입 권장 (0) | 2022.07.13 |
---|---|
자동주입 - 옵션 처리 (0) | 2022.07.11 |
싱글톤 컨테이너 (0) | 2022.07.08 |
스프링 빈 조회 (getBean) - 상속관계인 경우 (0) | 2022.07.06 |
(컨테이너에 등록된) 스프링 빈 조회해보기 (0) | 2022.07.06 |