[스프링 핵심원리 기본편] 컴포넌트 스캔

흑수·2022년 2월 2일
0

김영한씨의 스프링 핵심 원리 - 기본편 강의를 듣고 공부 겸 정리하는 글입니다.

컴포넌트 스캔과 의존관계 자동 주입 시작하기

지금까지는 @Bean 어노테이션을 통해 스프링 빈에 등록할 모든 것들을 지정했습니다. 갯수가 늘어나면 반복해서 작성해야할 코드가 적지 않은데요,,
이를 해결하기 위해 설정정보가 없어도 자동으로 스프링 빈을 등록하는 컴포넌트 스캔을 제공합니다.
또한 의존관계도 바로 주입하는 Autowired가 존재합니다.

@Configuration
@ComponentScan(
        excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classses = Configuration.class)
)
public class AutoAppConfig {
    
}

위처럼 @ComponentScan을 설정 정보에 붙여주기만 하면 @Bean을 따로 붙여줄 필요가 없습니다.
이름 그대로 @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;
      }
}

@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;
      }
}
  1. @Component
  • Component가 붙은 모든 클래스를 스프링 빈으로 등록
  • 클래스 메소드의 첫글자는 소문자로 변경해서 등록(OrderSerivceImpl -> orderServiceImpl)
빈 이름빈 객체
memberServiceImplMemberServiceImpl@x01
orderServiceImplOrderServiceImpl@x02
memoryMemberRepositoryMemoryMemberRepositoryImpl@x03
rateDiscountPolicyRateDiscountPolicyImpl@x04
  1. @Autowired
  • 스프링 컨테이너가 해당하는 것을 찾아서 자동으로 주입
  • 생성자에 파라미터가 많아도 다 찾아서 주입

탐색 위치와 기본 스캔 대상

탐색할 패키지의 시작 위치 지정

모든 클래스를 다 컴포넌트 스캔하면 시간이 오래 걸리기 때문에 탐색 위치를 지정할 수 있습니다.

@ComponentScan(
    basePackages = "hello.core"
)

지정하지 않으면 @ComponentScan이 붙은 설정 정보 클래스의 패키지가 시작 위치가 됩니다.

주로 권장하는 방법은 설정 정보 클래스를 프로젝트 상단에 두어 basePackages를 생략하는 방법입니다. 이렇게 하면 프로젝트 하부 패키지는 모두 스캔하기 때문이지요..

컴포넌트 스캔 기본 대상

@Component @Controller @Service @Repository @Configuration

해당 클래스들은 @Component를 포함하고 있습니다.

필터

  • includeFilteres: 스캔 대상 추가로 지정
  • excludeFilters : 스캔에서 제외 대상 지정

중복 등록과 충돌

두 가지의 상황이 존재합니다.

  1. 자동 빈 등록 vs 자동 빈 등록

컴포넌트 스캔에 의해 자동으로 등록 될 때, 이름이 같게 되면 무슨 일이 일어날까요?
정답은 ConflictingBeanDefinitionException 예외가 발생한다 입니다.

  1. 수동 빈 등록 vs 자동 빈 등록

이름이 같아 충돌하게 된다면 수동 빈 등록이 우선권을 가집니다. 즉, 수동 빈이 자동 빈을 오버라이딩 한다는 이야기,,
하지만, 최근에는 스프링 측에서 그냥 오류로 만들어 버린답니다.

profile
기록용

0개의 댓글