컴포넌트 스캔

강한친구·2022년 4월 7일
0

Spring

목록 보기
5/27

AppConfig

@Configuration
public class AppConfig {

    @Bean
    public MemberService memberService() {
        return new MemberServiceImpl(memberRepository());
    }

기존의 AppConfig에서 Bean 등록을 할때는 Bean Annotation을 붙여서 해결했다.

만약 이 빈이 5만개 있다면, 그걸 하나씩 다 등록하기에는 너무 귀찮고 관리도 어려울것이다.

그래서 나온게 컴포넌트 스캔이다.

AutoAppConfig

@Configuration
@ComponentScan(
//        basePackages = "hello.core.member",
        excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Configuration.class)
) // Configuration 빼고 자동스캔
public class AutoAppConfig {


}

자동으로 Component라는 Annotation이 붙은것들을 스캔한다.

@Component
public class MemoryMemberRepository implements MemberRepository {

이런식으로 붙이면 된다.

하지만 이러면, DI는 어떻게 처리되는걸까?

예를 들어, OrderServiceImpl을 보겠다.

@Component
public class OrderServiceImpl implements OrderService{
    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;
        
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }

이런식으로 생성자에 넣어줄 값이 AutoAppConfig에는 전혀 지정되어 있지 않다.

Autowired

이러한 문제는 AutoWired Annotation으로 해결 할 수 있다.

@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하면, 스프링이 알아서 잡아서 넣어준다.

다른 방식은 [이 글]을 보자

탐색위치와 필터

탐색위치

컴포넌트 스캔은 기본적으로 자신의 디렉토리와 그 하위 모든 디렉토리이다.
통상적으로 Package 최상위루트에 Config를 만들어서 전체스캔을 한다.

또는 exclude 옵션을 통해 스캔하지 않을 클래스를 지정할 수 있다.

필터

incldueFilter, excludeFilter를 통해서 필터옵션을 줄 수 있다.

필터 옵션은

ANNOTATION: 기본값, 애노테이션을 인식해서 동작한다.
ASSIGNABLE_TYPE: 지정한 타입과 자식 타입을 인식해서 동작한다.
ASPECTJ: AspectJ 패턴 사용
REGEX: 정규 표현식
CUSTOM: TypeFilter 이라는 인터페이스를 구현해서 처리

가 있다.

중복처리

1. 자동등록과 자동등록

이 경우 ConflictingBeanDefinition 오류메세지가 나온다.
그냥 이름만 안겹치게 해주면 된다.

2. 자동등록과 수동등록

이 경우 문제없이 실행이 된다. 이 경우 수동등록 빈이 우선권을 가지고 overring 해버린다.

그리고 스프링에서 Overriding 메세지가 나온다.

다만, 현업에서는 설정이 꼬여서 이러한 의도하지 않은 오버라이딩이 나올 수 있고, 이런 버그들은 찾을 수가 없다.
따라서 이런 애매한 상황을 안만들도록 하는게 제일 좋고,
이에 결국 스프링부트에서 중복상황에 오류를 뱉어내도록 바뀌었다.

0개의 댓글