@Autowired
라는 기능도 제공한다.@Configuration
@ComponentScan(
excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Configuration.class)
)
public class AutoAppConfig {
}
@ComponentScan
을 설정 정보에 붙여주면 된다.컴포넌트 스캔을 사용하면
@Configuration
이 붙은 설정 정보도 자동으로 등록되기 때문에, AppConfig, TestConfig 등 앞서 만들어두었던 설정 정보도 함께 등록되고, 실행되어 버린다.그래서
excludeFilters
를 이용해서 설정정보는 컴포넌트 스캔 대상에서 제외했다.보통 설정 정보를 컴포넌트 스캔 대상에서 제외하진 않지만, 기존 예제 코드를 남기고 유지하기 위해 사용한다.
- 컴포넌트 스캔은 이름 그대로
@Component
어노테이션이 붙은 클래스를 스캔해서 스프링 빈으로 등록한다.@Component
를 붙여주자.
@Configuration
이 컴포넌트 스캔의 대상이 된 이유도@Configuration
소스코드를 여렁보면@Component
어노테이션이 붙어있기 때문이다.
@Component
추가@Component
public class MemoryMemberRepository implements MemberRepository {
...
}
@Component
public class RateDiscountPolicy implements DiscountPolicy{
...
}
@Component
public class MemberServiceImpl implements MemberService{
private final MemberRepository memberRepository;
@Autowired
public MemberServiceImpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
...
}
@Bean
으로 직접 설정 정보를 작성했고, 의존관계도 직접 명시했다.@Autowired
는 의존관계를 자동으로 주입해준다.@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;
}
...
}
@Autowired
를 사용하면 생성자에서 여러 의존관계도 한번에 주입받을 수 있다.public class AutoAppConfigTest {
@Test
void basicScan() {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class);
MemberService memberService = ac.getBean(MemberService.class);
assertThat(memberService).isInstanceOf(MemberService.class);
}
}
AnnotationConfigApplicationContext
를 사용하는 것은 기존과 동일AutoAppConfig
클래스를 넘겨준다.13:44:42.031 [main] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [C:\workspace\Study\Spring_core\out\production\classes\hello\core\discount\RateDiscountPolicy.class]
13:44:42.033 [main] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [C:\workspace\Study\Spring_core\out\production\classes\hello\core\member\repository\MemoryMemberRepository.class]
13:44:42.035 [main] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [C:\workspace\Study\Spring_core\out\production\classes\hello\core\member\service\MemberServiceImpl.class]
13:44:42.037 [main] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [C:\workspace\Study\Spring_core\out\production\classes\hello\core\order\service\OrderServiceImpl.class]
@ComponentScan
은 @Component
가 붙은 모든 클래스를 스프링 빈으로 등록한다.@Component("{이름}")
과 같이 부여할 수 있다.@Autowired
를 지정하면, 스프링 컨테이너가 자동으로 해당 스프링 빈을 찾아서 주입한다.getBean(MemberRepository.class)
와 동일하다고 이해하면 된다.