Spring
[Spring] 컴포넌트 스캔
자동 주입과 함께 사용하는 추가 기능이 컴포넌트 스캔이다. 컴포넌트 스캔은 스프링이 직접 클래스를 검색해서 빈으로 등록해주는 기능이다. 설정 클래스에 빈으로 등록하지 않아도 원하는 클래스를 빈으로 등록할 수 있으므로 컴포넌트 스캔 기능을 사용하면 설정 코드가 크게 줄어든다.
@Component 애노테이션으로 스캔 대상 지정
스프링이 검색해서 빈으로 등록할 수 있으려면 클래스에 @Component 애노테이션이 붙어야 한다. @Component 애노테이션은 해당 클래스를 스캔 대상으로 표시한다.
@Component 애노테이션을 붙인 클래스만 컴포넌트 스캔 대상에 포함이 되는 것은 아니다. 다음 애노테이션을 붙인 클래스 또한 컴포넌트 스캔 대상에 포함된다. 아래 애노테이션 중, @Aspect를 제외한 애너테이션의 내부에는 @Component 애노테이션을 포함하고 있기 때문에, 자동으로 스캔 대상으로 등록되어 빈을 주입해주게 되어 있다.
- @Component
- @Controller
- @Service
- @Repository
- @Aspect
- @Configuration
@Component("infoPrinter")
public class MemberInfoPrinter {
private MemberDao memDao;
private MemberPrinter printer;
...
}
@Component 애노테이션에 값을 주었는지에 따라 빈으로 등록할 때 사용할 이름이 결정된다. 만약 @Component 애노테이션에 값을 주지 않으면, 클래스 이름의 첫 글자를 소문자로 바꾼 빈 이름을 사용한다. 예를 들면, MemberDao 클래스의 경우, memberDao라는 빈 이름을 사용하게 된다.
@Configuration
@ComponentScan(basePackages = {"spring"})
public class AppCtx {
...
}
@Component 애노테이션을 붙인 클래스를 스캔해서 스프링 빈으로 등록하려면 설정 클래스에 @ComponentScan 애노테이션을 적용해야 한다. 설정 클래스인 AppCtx에 @ComponentScan 애노테이션을 적용한 코드는 위와 같다.
스캔 대상에서 제외하거나 포함하기
excludeFilters 속성을 사용하면 스캔할 때 특정 대상을 자동 등록 대상에서 제외할 수 있다. 다음 코드는 excludeFilter 속성의 사용 예를 보여준다.
@Configuration
@ComponentScan(basePackages = {"spring"},
excludeFilters = {
@Filter(type = FilterType.REGEX, pattern = "spring\\..*Dao")
})
public class AppCtxWithExclude {
@Bean
public MemberDao memberDao() {
return new MemberDao();
}
...
}
이 코드는 @Filter 애노테이션의 type 속성 값으로 FilterType.REGEX를 주었다. 이는 정규표현식을 사용해서 제외 대상을 지정한다는 것을 의미한다. pattern 속성은 FilterType에 적용할 값을 설정한다. 위 설정에서는 "spring."으로 시작하고 Dao로 끝나는 정규표현식을 지정했으므로 springMemberDao 클래스를 컴포넌트 스캔 대상에서 제외한다.
FilterType.ASPECTJ를 필터 타입으로 설정할 수도 있다. 이 타입을 사용하면 정규 표현식 대신 AspectJ 패턴을 사용해서 대상을 지정한다.
@Configuration
@ComponentScan(basePackages = {"spring"},
excludeFilters = {
@Filter(type = FilterType.ASPECTJ, pattern="spring.*Dao" )
})
public class AppCtxWithExclude {
@Bean
public MemberDao memberDao() {
return new MemberDao();
}
...
}
AspectJ 패턴은 정규 표현식과는 다른데 위와 같은 경우, spring 패키지의 Dao로 끝나는 타입을 지정한다는 의미이다. 이 때, AspectJ 패턴이 동작하려면 의존 대상에 aspectjweaver 모듈을 추가해야 한다.
특정 애노테이션을 붙인 타입을 컴포넌트 대상에서 제외할 수도 있다. 예를 들어 @NoProduct나 @ManualBean 애노테이션을 붙인 클래스는 컴포넌트 스캔에서 제외하고 싶다고 할 경우 아래와 같이 설정한다.
@Configuration
@ComponentScan(basePackages = {"spring", "spring2" },
excludeFilters = {
@Filter(type = FilterType.ANNOTATION, classes = {NoProduct.class, ManualBean.class} )
})
public class AppCtxWithExclude {
@Bean
public MemberDao memberDao() {
return new MemberDao();
}
...
}
관련글
위 글은 스프링5 프로그래밍 입문 (저자: 최범균) 책을 공부하면서 작성한 글입니다. (링크)
'개발 > Spring' 카테고리의 다른 글
[Spring 프로젝트] Mybatis에서 Insert, Update Batch 처리하기 (0) | 2020.12.02 |
---|---|
[Spring 프로젝트] Junit5 테스트 코드 작성하기 (Junit4와 차이점 정리) (0) | 2020.11.20 |
[Spring] 스프링 의존 자동 주입 (Auto Injection)이란? (0) | 2020.11.16 |
[Spring 프로젝트] 2. ERD 설계하기 (0) | 2020.11.16 |
[Spring 프로젝트] 1. 프로젝트 기획하기 (0) | 2020.11.12 |