middlemoon

Spring - 컴포넌트 스캔 본문

Develop/Spring

Spring - 컴포넌트 스캔

중대경 2023. 3. 14. 08:00

이번 시간은 컴포넌트 스캔과 의존관계 자동주입에서 사용되는 @Component 와 @Autowired 에 대해서 알아볼 예정이다.

Autowired같은경우는 기존의 컨트롤러에 스프링Bean되어있는 Service단의 스프링 컨테이너화된 것들을 가져와

Autowired 하나로 의존관계 주입을 편리하게 한 기억이 있다. 오늘은 거기에 대하여 원리를 배우고자 글을 올리게 되었다.

 

 

 


 

이 블로그는 김영한님 강의를 토대로 작성하였으니 참고용으로 봐주시면 좋을 것 같고, 기록용으로 남기기 위해 올렸다는 점 참고해주시면 감사하겠습니다.

 

 

 

 

 

 

 

먼저 ComponentScan을 선언해줌으로써, 여러개의 Bean들을 한번에 모아서 써줄수 있도록 어노테이션으로 선언해준다.

 

 

 

 

사용하고자하는 부분에 Component를 어노테이션으로 추가해준다. Autowiredf를 선언해준다는 것은 해당하는 MemberRepository, DiscountPolicy를 의존성으로 사용할수 있다는 것을 의미한다.

 

 

 

 

 

 

테스트코드 성공

 

 

콘솔부분에

ClassPathBeanDefinitionScanner - Identified candidate component class: file [/Users/youngban/Desktop/core 3/out/production/classes/hello/core/discount/RateDiscountPolicy.class]

이면서

Creating shared instance of singleton bean 'rateDiscountPolicy'

 

이런식으로 뜨는 이유는 Component해준 클래스 범위에 성공적으로 Bean등록을 마쳤다는 의미를 나타내는 로그라고 생각하면 될것같다 

 

 

 

 

 

package hello.core.scan.filter;

import hello.core.scan.filter.BeanA;
import hello.core.scan.filter.BeanB;
import hello.core.scan.filter.MyExcludeComponent;
import hello.core.scan.filter.MyIncludeComponent;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
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.assertThat;
import static org.springframework.context.annotation.ComponentScan.Filter;
public class ComponentFilterAppConfigTest {
    @Test
    void filterScan() {
        ApplicationContext ac = new
                AnnotationConfigApplicationContext(ComponentFilterAppConfig.class);
        BeanA beanA = ac.getBean("beanA", BeanA.class);
        assertThat(beanA).isNotNull();
        Assertions.assertThrows(
                NoSuchBeanDefinitionException.class,
                () -> 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 {
    }
}

includeFilters MyIncludeComponent 애노테이션을 추가해서 BeanA가 스프링 빈에 등록된다.

위와 같은 코드는 테스트 코드 성공 BeanB도 포함

 

 

excludeFilters MyExcludeComponent 애노테이션을 추가해서 BeanB는 스프링 빈에 등록되지 않는다.

BeanB 제외

수동 빈 등록, 자동 빈 등록 오류시 스프링 부트 에러

Consider renaming one of the beans or enabling overriding by setting
spring.main.allow-bean-definition-overriding=true
Comments