Spring 시리즈는 혼자 공부하며 기록으로 남기고, 만약 잘못 학습 한 지식이 있다면 공유하며 피드백을 받고자 작성합니다.
스프링에 대해 깊게 공부해보고자 인프런의 김영한 강사님께서 강의를 진행하시는 (스프링 핵심 원리 - 기본편) 강의를 수강하며 정리하는 글입니다.
혹여나 글을 읽으시며 잘못 설명된 부분이 있다면 지적 부탁드리겠습니다.
@Bean이나 xml의 <bean> 등을 통해서 설정 정보에 직접 등록할 스프링 빈들을 작성하였다.@Autowired 기능도 제공한다.기존의 설정정보는 유지하기 위해 AutoAppConfig.java 를 새로 만들 것이다
AutoAppConfig.java
@Configuration
@ComponentScan(
excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Configuration.class)
)
public class AutoAppConfig {
}
@ComponentScan애노테이션을 설정 정보에 붙여줘야한다.참고: 원래는 @ComponentScan만 붙여주면 되지만 @Configuration 또한 컴포넌트 스캔의 대상이 되므로 현재 코드에서는 제외시켜주기위해 필터옵션을 추가했다.
보통 설정 정보를 컴포넌트 스캔 대상에서 제외하지 않지만, 기존 예제 코드를 최대한 남기고 유지하기 위해서 사용한다.
@Component 애노테이션이 붙은 클래스를 스캔해서 스프링 빈으로 등록하는 방식이다.@Configuration 애노테이션을 타고 들어가보면 @Component 애노테이션이 붙어있는걸 볼 수 있다.@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {}@Component 애노테이션을 추가해보자MemoryMemberRepository
@Component
public class MemoryMemberRepository implements MemberRepository {}
RateDiscountPolicy
@Component
public class RateDiscountPolicy implements DiscountPolicy {}
MemberServiceImpl
@Component
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
@Autowired // ac.getBean(MemberRepository.class) - 근데 만약 MemberRepository 타입이 두개면 어떻게되는걸까..
public MemberServiceImpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
@Autowired는 의존관계를 자동으로 주입해준다고 한다. 주석처리 되어있는것처럼 동작하는것같은데.. 만약 MemberRepository 타입이 여러개가 등록이 되어있다면? 어떻게되는걸까.. 라는 의문이 생긴다.(이것도 설명 해주시겠지..?)OrderServiceImpl
@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);
}
}
ClassPathBeanDefinitionScanner -- RateDiscountPolicy.class
ClassPathBeanDefinitionScanner -- MemberServiceImpl.class
ClassPathBeanDefinitionScanner -- MemoryMemberRepository.class
ClassPathBeanDefinitionScanner -- OrderServiceImpl.class
로그를 보면 잘 스캔되어 등록되는걸 볼 수 있다.

@ComponentScan은 @Component가 붙은 모든 클래스를 스프링 빈으로 등록한다.@Component("name") 으로 파라미터를 부여하면 된다.
@Autowired를 사용할때 어떻게 동작하는지 몰랐는데 먼저 컴포넌트를 스캔한 다음 필요한 의존관계를 스프링 컨테이너 안에서 가져와 주입해주는 방식인가보다.