개발/Spring

[Spring] 컴포넌트 스캔

nova_dev 2020. 11. 17. 09:00
반응형

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 프로그래밍 입문 (저자: 최범균) 책을 공부하면서 작성한 글입니다. (링크)

 
 

 

 

반응형