• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

컴포넌트 스캔 - 필터 수강 중 질문

23.04.01 19:09 작성 23.04.01 19:41 수정 조회수 253

0

안녕하세요. 스프링 핵심 원리 기본편 중 컴포넌트 스캔의 필터 강의를 수강하던 중 에러가 생겼습니다. 에러는 해결했지만 궁금한 점이 생겨 질문 드립니다. 구분선을 기준으로 안에 있는 말들은 모두 상황의 이해를 돕기 위한 말들이니 질문만 보고 싶으시면 구분선 밖 마지막 말만 보셔도 괜찮으실 거라 생각합니다.

 


제가 작성한 코드는 다음과 같고 강의의 제목과 같이 컴포넌트 스캔의 필터 부분을 학습하기 위한 예제 코드입니다.

 

package hello.core.scan.filter;

import java.lang.annotation.*;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyIncludeComponent {
}

MyIncludeComponent라는 애노테이션을 생성하고

 

package hello.core.scan.filter;

import org.springframework.stereotype.Component;

@MyIncludeComponent
public class BeanA {
}

위와 같이 해당 애노테이션이 붙는 클래스 BeanB를 생성하고

 

package hello.core.scan.filter;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;

import static org.assertj.core.api.Assertions.*;
import static org.springframework.context.annotation.ComponentScan.*;

public class ComponentFilterAppConfigTest {

    @Test
    void filterScan(){
        ApplicationContext ac = new AnnotationConfigApplicationContext(ComponentFilterAppConfig.class);
        BeanA beanA = ac.getBean("beanA", BeanA.class);
        assertThat(beanA).isNotNull();

//        BeanB beanB = ac.getBean("beanB", BeanB.class);
    }

    @Configuration
    @ComponentScan(
            includeFilters = @Filter(type = FilterType.ANNOTATION, classes = MyIncludeComponent.class),
            excludeFilters = @Filter(type = FilterType.ANNOTATION, classes = MyExcludeComponent.class)
            )
    static class ComponentFilterAppConfig{
    }
}

위와 같이 테스트 코드를 만들어 실행하였습니다.

ComponenScan을 이용해 MyIncludeComponent 애노테이션이 붙은 클래스를 자동으로 빈으로 등록시키고 조회하는 테스트 코드입니다.

(MyExcludeComponent 애노테이션이나 해당 애노테이션을 붙힌 BeanB 클래스는 현재 질문과 관계가 없다고 판단해 코드를 생략하였습니다.)

그런데 해당 테스트 코드를 실행하니 beanA라는 이름의 빈을 컨테이너에서 찾을 수 없다는 에러가 떴습니다.

여러 방법으로 찾아보던 중 @ComponentScan 애노테이션의 includeFilters 속성과 @MyIncludeComponent 애노테이션을 올바르게 사용하여도, BeanA 클래스가 스프링 컨테이너에 등록되지 않는 경우가 생길 수 있고 이를 해결하기 위해선 @Component 애노테이션이나 @Service, @Repository 등과 같은 스프링이 제공하는 스테레오 타입 애노테이션 중 하나를 BeanA 클래스에 추가하여 해당 클래스를 스프링 빈으로 등록해야 한다는 해결책을 발견했고 그대로 따라했습니다.

 

BeanA 클래스에 @Component 애노테이션을 붙혀 테스트 코드를 그대로 다시 실행하였고 에러는 해결이 되었습니다. 그래서 BeanA 클래스의 @Component 애노테이션을 다시 제거한 후 테스트 코드를 돌렸는데 성공하였습니다.

 


이런 일이 왜 발생하는지 제대로 이해가 안 되어서 질문 드립니다.

@ComponentScan 애노테이션의 includeFilters 속성과 @MyIncludeComponent 애노테이션을 올바르게 사용하여도, BeanA 클래스가 스프링 컨테이너에 등록되지 않는 경우가 생길 수 있는 것인가요? 또 어떤 원리로 이렇게 등록이 안 되는 경우가 생기는지가 궁금합니다!

답변 1

답변을 작성해보세요.

0

David님의 프로필

David

2023.04.04

안녕하세요. kmskes0917님, 공식 서포터즈 David입니다.

아래 가이드를 따라 프로젝트를 공유해 주시면 살펴보겠습니다.

전체 프로젝트를 압축해서 구글 드라이브로 공유해서 링크를 남겨주세요.
구글 드라이브 업로드 방법은 다음을 참고해주세요.

구글 드라이브 업로드 방법 링크

주의: 업로드시 권한 문제 꼭 확인해주세요

추가로 다음 내용도 코멘트 부탁드립니다.

1. 실행 방법을 알려주세요.
2. 어떻게 문제를 확인할 수 있는지 자세한 설명을 남겨주세요.

감사합니다.