• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

컴포넌트 스캔 관련 질문

23.10.08 20:45 작성 조회수 255

0


[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)

[질문 내용]
여기에 질문 내용을 남겨주세요.

 

package hello.core;


import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;

@Configuration
@ComponentScan(
        basePackages = "hello.core",
        excludeFilters =
      @ ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Configuration.class))
public class AutoAppConfig {

}
package hello.core;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class CoreApplication {

    public static void main(String[] args) {
       SpringApplication.run(CoreApplication.class, args);
    }

}
package hello.core;

import hello.core.discount.DiscountPolicy;
import hello.core.discount.FixDiscountPolicy;
import hello.core.discount.RateDiscountPolicy;
import hello.core.member.MemberRepository;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import hello.core.member.MemoryMemberRepository;
import hello.core.order.OrderService;
import hello.core.order.OrderServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {
    @Bean
    //MemoryMemberRespository 객체로 초기화된 MemberServiceImpl 객체 반환
    public MemberService memberService() {
        System.out.println("call AppConfig.memberService");
        return new MemberServiceImpl(memberRepository());
    }


    @Bean
    public OrderService orderService() {
        System.out.println("call AppConfig.orderService");
        return new OrderServiceImpl (
                memberRepository(),
                discountPolicy()
        );
    }
    @Bean
    public MemberRepository memberRepository() {
        System.out.println("call AppConfig.memberRepository");
        return new MemoryMemberRepository();
    }


    @Bean
    public DiscountPolicy discountPolicy() {
        return new RateDiscountPolicy();
    }

}

 

ㅇCoreApplicaton 클래스(@SpringBootApplicaton)

을 실행하면,

 

@SpringBootApplicaton 에 @ComponentScan이

포함되어 있기 때문에 CoreApplication 의 패키지 하위를

전부 scan 합니다.

그 과정에서 AppConfig 와 AutoAppConfig 를 만날텐데

@ ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Configuration.class))

AutoAppConfig에 @Configuration 은 스캔하지 말라고

되어있습니다.

 

Q1. 그러면 AppConfig 는 스캔 되지 않고 빈으로 생성되지 않는 건가요?

Q2. AutoAppConfig도 @Configuration이 등록되어있는데

그렇다면 AutoAppConfig도 빈으로 생성되지 않는건가요?

Q3.

@Configuration
public class AppConfig {
    @Bean
    //MemoryMemberRespository 객체로 초기화된 MemberServiceImpl 객체 반환
    public MemberService memberService() {
        System.out.println("call AppConfig.memberService");
        return new MemberServiceImpl(memberRepository());
    }


    @Bean
    public OrderService orderService() {
        System.out.println("call AppConfig.orderService");
        return new OrderServiceImpl (
                memberRepository(),
                discountPolicy()
        );
    }
    @Bean
    public MemberRepository memberRepository() {
        System.out.println("call AppConfig.memberRepository");
        return new MemoryMemberRepository();
    }


    @Bean
    public DiscountPolicy discountPolicy() {
        return new RateDiscountPolicy();
    }

}

AppConfig 를 컴포넌트 스캔 대상에서 제외해버리면

AppConfig의 수동 빈 등록 내용도 전부 무시되어 얘네들이

빈으로 생성되지 않는건가요?

 

Q4.CoreApplicaotn 에도 @Configuration 이,

AutoAppConfig에도 @Configuration이 설정되어있는데

이 경우 충돌이 일어나지는 않나요?

 

Q5.

만약 Q4에서 충돌이 일어나지 않는다면, 두개의 Configuraiton 내용이 둘다 프로젝트에 적용되는 건가요?

답변 2

·

답변을 작성해보세요.

1

안녕하새요 재윤님

Q1~Q5의 답변을 종합해서 정리해드리겠습니다.

이런 경우에는 스프링 부트의 설정이 먼저 적용됩니다. 따라서 AppConfig, AutoAppConfig도 함께 스캔이 되고, 빈으로 생성됩니다. 이 경우 AutoAppConfig의 설정은 무시됩니다.

만약 컴포넌트 스캔에 대한 부분을 따로 설정하고 싶다면 스프링 부트를 실행하는 @SpringBootApplication 애노테이션이 있는 CoreApplication에 컴포넌트 스캔을 원하시는 대로 다시 정의하시면 됩니다.

감사합니다.

 

재윤님의 프로필

재윤

질문자

2023.10.15

그렇군요 ㅎㅎ. 이해했습니다. 답변 달아주셔서 감사합니다!!

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2023.10.10

안녕하세요, 인프런 AI 인턴이에요.

컴포넌트 스캔은 스프링 프레임워크에서 자동으로 빈을 등록하는 기능입니다. @ComponentScan 어노테이션을 사용하여 어떤 패키지부터 스캔할지 설정하고, 설정한 패키지 내에서 @Component 어노테이션이 붙은 클래스를 찾아서 빈으로 등록합니다.

AutoAppConfig 클래스에서는 @Configuration 어노테이션을 붙이고, @ComponentScan 어노테이션을 사용하여 hello.core 패키지를 스캔하도록 설정하고 있습니다. 또한, @ComponentScan 어노테이션 내에서 excludeFilters 속성을 사용하여 Configuration.class 어노테이션이 붙은 클래스는 제외하도록 설정하고 있습니다.

CoreApplication 클래스에서는 @SpringBootApplication 어노테이션을 사용하고 있습니다. 이 어노테이션은 프로젝트를 실행하는 데 필요한 기본 설정을 자동으로 해줍니다.

그리고 hello.core 패키지 내에는 MemberRepository 인터페이스와 MemberService 인터페이스를 구현한 클래스들, 그리고 DiscountPolicy 인터페이스를 구현한 클래스들이 있습니다.

AutoAppConfig 클래스에 @ComponentScan 어노테이션을 통해 hello.core 패키지를 스캔하도록 설정하였기 때문에, 해당 패키지 내에서 @Component 어노테이션이 붙은 클래스들은 자동으로 빈으로 등록될 것입니다.

이렇게 자동으로 빈으로 등록해주는 컴포넌트 스캔 기능을 사용하면, 개발자는 직접 빈을 등록하는 코드를 작성할 필요 없이 편리하게 빈을 관리할 수 있습니다.