작심삼일러의 스프링 시작하기(4)

서은경·2022년 7월 28일
0

Spring

목록 보기
7/43

컴포넌트 스캔

컴포넌트 스캔은 스프링이 직접 클래스를 검색해서 빈으로 등록해주는 기능이다. 설정 클래스에 빈으로 등록하지 않아도 원하는 클래스를 빈으로 등록할 수 있어 설정 코드가 크게 줄어든다.

@Component

스프링이 검색해서 빈으로 등록할 수 있으려면 클래스에 @Component 어노테이션을 붙여야한다. @Component 어노테이션은 해당 클래스를 스캔 대상으로 표시한다.

@Component
public class MemberDao {

(생략..)

@Component 어노테이션을 붙인 클래스를 스캔해서 스프링 빈으로 등록하려면 설정 클래스에 @ComponentScan 어노테이션을 적용해야 한다. 스캔 대상에 해당하는 클래스 중에서 @Component 어노테이션이 붙은 클래스의 객체를 생성해서 빈으로 등록한다.


@Configuration
@ComponentScan(basePackages = {"spring"})
// 스캔 대상 패키지 목록 지정, spring 패키지와 하위 패키지에 속한 클래스를 스캔 대상으로 설정
public class AppCtx {

    /* Component 설정했으므로 설정파일에 빈을 등록해줄 필요가 없음!
    @Bean
    public MemberDao memberDao() {
        return new MemberDao();
    }

    @Bean
    public MemberRegisterService memberRegSvc() {
        return new MemberRegisterService();
    }

    @Bean
    public ChangePasswordService changePwdSvc() {
        ChangePasswordService pwdSvc = new ChangePasswordService();
        return pwdSvc;
    }

    @Bean
    public MemberInfoPrinter memberInfoPrinter() {
        MemberInfoPrinter infoPrinter = new MemberInfoPrinter();
        return infoPrinter;
    }

    @Bean
    public MemberListPrinter memberListPrinter() {
        return new MemberListPrinter();
    }
    */
    @Bean
    @Qualifier("printer")
    public MemberPrinter memberPrinter() {
        return new MemberPrinter();
    }

    @Bean
    public MemberSummaryPrinter memberPrinter2() {
        return new MemberSummaryPrinter();
    }

    @Bean
    public VersionPrinter versionPrinter() {
        VersionPrinter versionPrinter = new VersionPrinter();
        versionPrinter.setMajorVersion(5);
        versionPrinter.setMinorVersion(0);
        return versionPrinter;
    }

}

스캔 대상에서 제외하거나 포함하기

excludeFilters 속성을 사용하면 특정 대상을 자동 등록 대상에서 제외할 수 있다.

@Configuration
@ComponentScan(basePackages = {"spring"},
excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = "spring\\..*Dao"))
// FilterType.REGEX : 정규표현식을 사용해서 제외 대상 지정
// pattern = "spring\\..*Dao : spring.으로 이작하고 Dao로 끝나는 정규표현식 지정

// ASPECTJ 패턴
// excludeFilters = @ComponentScan.Filter(type = FilterType.ASPECTJ, pattern = "spring.*Dao")
public class AppCtxWithExclude {

    @Bean
    public MemberDao memberDao() {
        return new MemberDao();
    }
}

기본 스캔 대상

@Component 어노테이션을 붙인 클래스만 컴포넌트 스캔 대상에 포함 되는 것은 아니다.

  • @Component (org.springframework.stereotype 패키지)
  • @Controller (org.springframework.stereotype 패키지)
  • @Service (org.springframework.stereotype 패키지)
  • @Repository (org.springframework.stereotype 패키지)
  • @Aspect (org.aspectj.lang.annotation 패키지)
  • @Configuration (org.springframework.context.annotation 패키지)

@Aspect 어노테이션을 제외한 나머지는 실제로 @Component 어노테이션에 대한 특수 어노테이션이다.

컴포넌트 스캔에 따른 충돌 처리

컴포넌트 스캔 기능을 사용해서 자동으로 빈을 등록할 때에는 충돌에 주의해야 한다. 크게 빈 이름 충돌과 수동 등록에 따른 충돌이 발생할 수 있다.

  1. 빈 이름 충돌
    컴포넌트 스캔 과정에서 서로 다른 타입인데 같은 빈 이름을 사용하는 경우가 있다면 둘 중 하나에 명시적으로 빈 이름을 지정해서 이름 충돌을 피해야 한다.
  2. 수동 등록 충돌
    스캔할 때 사용하는 빈 이름과 수동 등록한 빈 이름이 같은 경우 수동 등록한 빈이 우선한다!

0개의 댓글