ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [스프링] 컴포넌트 스캔
    Spring 2022. 10. 3. 10:19

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

    1. @Component 어노테이션으로 스캔 대상 지정

    • 스프링이 검색해서 빈으로 등록할 수 있으려면 클래스에 @Component 어노테이션을 붙여야 한다.
    @Component
    public class MemberDao {
    
    	private static long nextId = 0;
    	private Map<String, Member> map = new HashMap<>();
    
    	public Member selectByEmail(String email) {
    		return map.get(email);
    	}
        ... 생략
    }

     

    Component 어노테이션에서 빈의 이름으로 쓸 값을 지정하지 않을 경우, 클래스 이름의 맨 앞글자를 소문자로 바꿔 memberDao를 빈의 이름으로 자체 등록하여 사용한다. 반면 아래와 같이 Component 어노테이션에 값을 주면, 그 값을 빈의 이름으로 쓸 수 있다.

     

    @Component("listPrinter")
    public class MemberListPrinter {
        private MemberDao memberDao;
        ... 생략
    }

     

     

    2. @ComponentScan 어노테이션으로 스캔 대상 설정 및 제외하기

     

    • Component 어노테이션이 붙은 클래스를 스캔해서 스프링 빈으로 등록하려면 우선 설정 클래스에 @ComponentScan 어노테이션을 적용해야 한다.
    @Configuration
    @ComponentScan(basePackages = {"spring"})
    public class AppCtx {
    
    	@Bean
    	@Qualifier("printer")
    	public MemberPrinter memberPrinter1() {
    		return new MemberPrinter();
    	}
    	... 생략
    }

     

     

    • basePackages에 속성을 등록하므로써 스캔 대상 패키지 목록을 지정한다.
    • 위의 코드 @ComponentScan(basePackages = {"spring"})는 현재 프로젝트내에 존재하는 spirng패키지, 그리고 spring패키지 하위 패키지에 속한 모든 클래스를 스캔대상으로 설정한다는 의미이다.

     

    • 반면 excludeFilters 속성을 이용하면 스캔할 때 특정 대상을 자동 등록 대상에서 제외할 수 있다.
    @Configuration
    @ComponentScan(basePackages = {"spring", "spring2" }, 
    	excludeFilters = { 
    			@Filter(type = FilterType.ANNOTATION, classes = ManualBean.class )			
    })
    public class AppCtxWithExclude {
    	@Bean
    	public MemberDao memberDao() {
    		return new MemberDao();
    	}
    	... 생략
    }

     

    type 속성값으로 FilterType.ANNOTATION을 사용하면 classes 속성에서 필터로 사용할 어노테이션 타입을 값으로 준다.

    이제 @ManualBean이 붙은 클래스는 스캔대상에서 제외한다.

    • 기본 스캔 대상 : @Component 어노테이션뿐만 아니라 아래의 어노테이션이 붙은 클래스도 스캔 대상에 포함된다.
      1. @Component (org.springframework.stereotype 패키지)
      2. @Controller (org.springframework.stereotype 패키지)
      3. @Service (org.springframework.stereotype 패키지)
      4. @Repository (org.springframework.stereotype 패키지)
      5. @Aspect (org.aspectj.lang.annotation 패키지)
      6. @Configuration (org.springframework.context.annotation 패키지)

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

    • 컴포넌트 스캔 기능을 사용해서 자동으로 빈을 등록할 때는 충돌에 주의해야 한다.
    • 스캔할 때 등록한 빈 이름이 같은 경우 수동 등록한 빈이 우선 스캔된다.

     

     

    Q : 컴포넌트 스캔 기능을 이용할때 다른 패키지에 같은 이름의 클래스가 존재할 경우 어떻게 될까?

    A : 위의 예를 들어보자. @ComponentScan(basePackages = {"spring", "spring2"})로 스캔 범위를 설정하고 스프링 컨테이너를 생성하면 spring2 패키지에 있는 MemberRegisterService 클래스를 빈으로 등록할 때, 빈 이름인 memberRegisterService가 spring 패키지에 있는 MemberRegisterService 클래스의 빈과 타입이 다르다고 충돌이 일어난다.

     

     

    'Spring' 카테고리의 다른 글

    [스프링] Aspect Oriented Programming (AOP을 이용한 로깅파일 구성)  (0) 2023.08.05
    SOLID 원칙  (0) 2023.02.21
    MVC모델의 정의, 장점  (0) 2023.02.08
    [스프링] 의존성 주입2  (0) 2022.10.03
    [스프링] 의존성 주입1  (0) 2022.10.03

    댓글

Designed by Par3k