스프링 컴포넌트 스캔 🌿

이성혁·2021년 8월 1일
1

Spring

목록 보기
4/5
post-thumbnail

개인적으로 어려웠던 스프링의 원리과 사용기술을 학습하기 위하여 작성한 글입니다. 많은 내용을 참고하여 내용을 정리하였습니다. 수정사항이 있다면 언제든 지적해주세요!!

이전 글 - 스프링 기초와 원리를 알아보자🌳 에서 작성된 예제코드를 기반으로 내용을 작성되었습니다.

🔥 오늘의 주제는?

  • 지금까지 스프링 빈을 등록할 때는 자바 코드의 @Bean 통해서 설정 정보에 직접 등록할 스프링 빈을 나열했다.
  • 이렇게 등록해야 할 스프링 빈이 수백개가 되면 일일이 등록하기 어렵다.
  • 스프링은 설정 정보가 없어도 자동으로 스프링 빈을 등록하는 컴포넌트 스캔이라는 기능을 제공한다.
  • 코드로 컴포넌트 스캔과 의존관계 자동 주입을 알아보자.

  • @Configuration
    • 스프링 설정파일로 사용하기 위함
  • @ComponentScan
    • 컴포넌트 스캔을 사용하려면 설정 정보를 붙여주면 된다.
  • @ComponentScan 에서 excludeFilters 옵션을 사용한 이유는 다른 설정파일에서 설정정보가 등록되는 것을 막기위함이다.
  • 이번에 학습할 내용을 위하여 다른 설정은 제외한 것이다.(일반적으로 잘 사용하지 않음)
  • 컴포넌트 스캔은 이름 그대로 @Component 애노테이션이 붙은 클래스를 스캔해서 스프링 빈으로 등록한다. 자동으로 스프링 빈으로 등록을 위해 @Component 애노테이션을 붙이도록 하겠다.

MemoryMemberRepository, RateDiscountPolicy, MemberServiceImpl, OrderServiceImpl@Component 을 추가하였다.

주의사항

  • 이전에 AppConfig 에서는 @Bean 으로 직접 설정 정보를 작성했고, 의존관계도 직접 명시했다. 이제는 이런 설정 정보 자체가 없기 때문에, 의존관계 주입도 이 클래스 안에서 해결해야 한다.
  • 여기서 우리는 @Autowired 를 이용하여 의존관계를 자동으로 주입시켜 준다.
  • @Autowired 를 사용하면 생성자에서 여러 의존관계도 한번에 주입받을 수 있다.
  • 스프링 빈이 제대로 등록되었는지 코드로 확인해보자.
public class AutoAppConfigTest {

    @Test
    void basicScan() {
        
        //스프링 컨테이너 조회
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class);

        //스프링 빈 조회
        MemberService memberService = ac.getBean(MemberService.class);
        assertThat(memberService).isInstanceOf(MemberService.class);
    }
    
}

실행결과

  • 실행 로그를 살펴보니 우리가 @Component 애노테이션을 등록한 클래스는 모두 스프링 빈으로 등록되었다.
  • 그리고 @Autowired 애노테이션이 생성자를 통해 의존관계를 자동으로 주입하였다.
  • Autowiring by type from bean name 'memberServiceImpl' via constructor to bean named 'memoryMemberRepository'

정리

  • @ComponentScan

    • @ComponentScan@Component 가 붙은 모든 클래스를 스프링 빈으로 등록한다.
    • 빈 이름 기본 전략: MemberServiceImpl 클래스 memberServiceImpl
    • 빈 이름 직접 지정: 만약 스프링 빈의 이름을 직접 지정하고 싶으면, @Component("memberService2") 이런식으로 이름을 부여하면 된다.
  • @Autowired

    • 생성자에 @Autowired 를 지정하면, 스프링 컨테이너가 자동으로 해당 스프링 빈을 찾아서 주입한다.
    • 기본 조회 전략은 타입이 같은 빈을 찾아서 주입한다.

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

  • 모든 자바 클래스를 다 컴포넌트 스캔하면 시간이 오래 걸린다. 그래서 꼭 필요한 위치부터 탐색하도록 시작 위치를 지정할 수 있다.
  • basePackages : 탐색할 패키지의 시작 위치를 지정한다. 이 패키지를 포함해서 하위 패키지를 모두 탐색한다.
  • basePackageClasses : 지정한 클래스의 패키지를 탐색 시작 위치로 지정한다.
  • 만약 지정하지 않으면 @ComponentScan 이 붙은 설정 정보 클래스의 패키지가 시작 위치가 된다.

참고로 스프링 부트를 사용하면 스프링 부트의 대표 시작 정보인 @SpringBootApplication 를 이 프로젝트 시작 루트 위치에 두는 것이 관례이다. (그리고 이 설정안에 바로 @ComponentScan 이 들어있다)

컴포넌트 스캔 기본 대상

  • 컴포넌트 스캔은 @Component 뿐만 아니라 다음과 내용도 추가로 대상에 포함한다.
    • @Component : 컴포넌트 스캔에서 사용
    • @Controlller : 스프링 MVC 컨트롤러에서 사용
    • @Service : 스프링 비즈니스 로직에서 사용
    • @Repository : 스프링 데이터 접근 계층에서 사용
    • @Configuration : 스프링 설정 정보에서 사용
  • 해당 애노테이션의 소스를 살펴보면 @Component 을 포함하고 있는것을 알 수 있다.

  • 컴포넌트 스캔의 용도 뿐만 아니라 다음 애노테이션이 있으면 스프링은 부가 기능을 수행한다.
  • @Controller : 스프링 MVC 컨트롤러로 인식한다.
  • @Repository : 스프링 데이터 접근 계층으로 인식하고, 데이터 계층의 예외를 스프링 예외로 변환해준다.
  • @Configuration : 앞서 보았듯이 스프링 설정 정보로 인식하고, 스프링 빈이 싱글톤을 유지하도록 추가 처리를 한다.
  • @Service : 사실 @Service 는 특별한 처리를 하지 않는다. 대신 개발자들이 핵심 비즈니스 로직이 여기에
    있겠구나 라고 비즈니스 계층을 인식하는데 도움이 된다.

🌈 핵심정리

  • 이전에 스프링 빈을 등록하는 방법은 @Bean 을 사용하는 것이였다. 하지만 빈을 등록하기 위해 모두 애노테이션을 추가하는 것은 매우 번거로운 일이다. 스프링은 자동으로 스프링 빈으로 등록하도록 도와준다.
  • 바로 @Component 애노테이션을 이용하는 것이다. 이렇게 되면 @ComponentScan 을 이용하여 자동으로 탐색하고 스프링 빈으로 등록한다.
  • 이 과정에서 스프링 의존관계를 자동으로 주입시켜주는 기능인 @Autowired 애노테이션을 사용하여 의존관계를 주입시킨다.
  • @ComponentScan 은 탐색 시작 위치를 지정할 수 있는데, 지정하지 않으면 @ComponentScan 이 붙은 설정 정보 클래스의 패키지가 시작 위치가 된다.
  • @SpringBootApplication 애노테이션에는 @ComponentScan 이 들어있다. 따라서 프로젝트를 실행하게 되면 루트에 있는 시작클래스부터 하위경로에 있는 모든 패키지를 탐색하여 자동으로 스프링 빈으로 등록한다.

학습에 도움이 되었던 자료

Github 이동

profile
항상 배우는 자세로 🪴

0개의 댓글