인프런 커뮤니티 질문&답변
DiscountService 빈으로 등록 할 때 질문 드립니다.
작성
·
265
0
안녕하세요!! 질문 있어서 글 남깁니다.
AutoAppConfig.class를 제외하고 new AnnotationConfigApplicationContext(DiscountService.class)를 생성 할 때 DiscountService는 빈으로 등록이 되는데 DiscountPolicy를 구현한 구현체들(RateDiscountPolicy, FixDiscountPolicy)는 왜 빈으로 등록이 안되는지 궁금합니다.
스프링 컨테이너가 DiscountService를 빈으로 등록 할때 @Autowired가 추가된 생성자를 통해서 빈으로 등록을 하는데, 그때 생성자에 있는 DisocuntPolicy도 컨테이너가 자동으로 스캔해서 의존관계 주입을 하면서 빈으로 등록하는것이 아닌가요?
예를 들어서, OrderServiceImple의 경우에는 ComponentScan의 대상이 되어서 빈으로 등록 될 때 스프링 컨테이너가 생성자에 있는 MemberRepository 와 DiscountPolicy를 자동으로 스캔해서 빈으로 등록 된다고 알고 있었는데 제가 어떤것을 놓치고 있을까요?
퀴즈
필드 주입(Field Injection) 방식이 일반적으로 권장되지 않는 이유는 무엇일까요?
불변성을 보장하기 어려워서
의존성 변경이 쉬워서
순수 Java 코드로 테스트하기 어려워서
설정 코드 작성이 복잡해서
답변 2
2
안녕하세요. lim3617님, 공식 서포터즈 David입니다.
AnnotationConfigApplicationContext(DiscountService.class)만으로는 @ComponentScan이 발생하지 않습니다. DiscountService.class에는 @ComponentScan이 붙어있지 않기 때문입니다.
AutoAppConfig를 컨테이너 생성 파라미터로 넘겨야, AutoAppConfig가 bean definition에 등록되고, 이를 바탕으로 @ComponentScan이 붙어있는지 확인한 후 컴포넌트 스캔이 진행됩니다.
스프링 프로젝트의 경우, 아래와 같이 main 메서드가 내에 run(SpringGradlePlaygroundApplication.class, args) 메서드가 있습니다. SpringGradlePlaygroundApplication.class를 넘겨주면 @SpringBootApplication(@ComponentScan을 포함)애노테이션을 읽어 컴포넌트 스캔을 진행하게 됩니다.
@SpringBootApplication
public class SpringGradlePlaygroundApplication {
public static void main(String[] args) {
SpringApplication.run(SpringGradlePlaygroundApplication.class, args);
}
}
따라서 엄밀히 따지면 무조건 스프링 컨테이너가 로딩된다고 컴포넌트 스캔이 진행되는 것은 아닙니다.
AnnotationConfigApplicationContext(DiscountService.class) 이렇게만 작성하면, DiscountService만 빈으로 등록됩니다.
DiscountService내부에 @ComponentScan, @Bean과 같은 게 없다면 스프링 내부적으로 등록하는 빈이 아니고선 추가적으로 등록되는 빈이 없습니다.
따라서, AutoAppConfig를 컨테이너를 생성할 때 추가함으로써 ComponentScan이 발생되게 하여 AutoAppConfig가 속한 패키지와 그 하위 패키지의 @Component가 스캔되어 빈으로 등록되게 합니다.
감사합니다.
0





