상세 컨텐츠

본문 제목

[스프링1] 5장. 컴포넌트 스캔

22-23/22-23 Spring 1

by YUZ 유즈 2022. 11. 5. 10:01

본문

728x90

해당 포스트는 초보 웹 개발자를 위한 스프링 5 프로그래밍 입문 [최범균 저] 책 내용을 참고하였습니다.


❗@Component : 스캔 대상

📌사용법

  • @Component: 기본

        1. MemberDao(→memberDao), ChangePasswordService(→changePasswordService), MemberRegisterService(→memberRegisterService)

@Component
public class MemberDao {
	...
}

       2. MemberInfoPrinter(→infoPrinter), MemberListPrinter(→listPrinter)

@Component("infoPrinter")
public class MemberInfoPrinter {
	...
}
  • @Controller : 웹 MVC
  • @Service
  • @Repository : DB 연동
  • @AspectJ
  • @Configuration

 

❗@ComponentScan : 스캔 설정

📌사용법

설정 클래스에 @ComponentScan 애노테이션을 추가한다.

@Configuration
@ComponentScan(basePackages = {"spring"})
public class AppCtx {

	@Bean
	@Qualifier("printer")
	public MemberPrinter memberPrinter1() {
		return new MemberPrinter();
	}
	
	@Bean
	@Qualifier("summaryPrinter")
	public MemberSummaryPrinter memberPrinter2() {
		return new MemberSummaryPrinter();
	}
	
	@Bean
	public VersionPrinter versionPrinter() {
		VersionPrinter versionPrinter = new VersionPrinter();
		versionPrinter.setMajorVersion(5);
		versionPrinter.setMinorVersion(0);
		return versionPrinter;
	}
}

@Component 애노테이션을 추가한 클래스는 설정 클래스에서 따로 @Bean 등록을 하지 않아도 되어 코드가 간단해진다.

  • @ComponentScan : 해당 설정 클래스를 포함하고 있는 패키지 탐색
  • @ComponentScan(basePackages = {”….”}) : 스캔 대상 패키지 지정, 하위 패키지 탐색

 

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

  • excludeFilters
  • includeFilters
@ComponentScan(excludeFilters = { @Filter(type = FilterType.ANNOTATION, classes = ManualBean.class )})

 

@Filter 애노테이션

1. FilterType.REGEX : 정규표현식 패턴 지정, pattern

@ComponentScan(excludeFilters = @Filter(type = FilterType.REGEX, pattern = "spring\\..*Dao" ))

2. FilterType.ASPECTJ : AspectJ 패턴 지정(dependency에 aspectjweaver모듈 추가), pattern

@ComponentScan(excludeFilters = @Filter(type = FilterType.ASPECTJ, pattern = "spring.*Dao" ))

3. FilterType.ANNOTATION : 특정 애노테이션 지정, classes

@ComponentScan(excludeFilters = @Filter(type = FilterType.ANNOTATION, classes = {NoProduct.class, ManualBean.class} ))

4. FilterType.ASSIGNABLE_TYPE : 특정 타입이나 그 하위 타입 지정, classes

@ComponentScan(excludeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = MemberDao.class ))

 

 

❗예제 실행

기존에 @Bean 을 통해 수동 빈 등록을 하면서 메소드 이름이 빈 이름으로 설정되었기 때문에 그 부분을 수정해주어야 한다.

public class MainForSpring {
	...
	private static void processNewCommand(String[] arg) {
		...
		MemberRegisterService regSvc = ctx.getBean(MemberRegisterService.class); //
		...
	}

	private static void processChangeCommand(String[] arg) {
		...
		ChangePasswordService changePwdSvc = ctx.getBean(ChangePasswordService.class); //
		...
	}

	private static void processListCommand() {
		MemberListPrinter listPrinter = ctx.getBean("listPrinter", MemberListPrinter.class); //
		...
	}

	private static void processInfoCommand(String[] arg) {
		...
		MemberInfoPrinter infoPrinter = ctx.getBean("infoPrinter", MemberInfoPrinter.class); //
		...
	}
	
	private static void processVersionCommand() {
		VersionPrinter versionPrinter = ctx.getBean("versionPrinter", VersionPrinter.class); //
		...
	}

}

 

 

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

📌빈 이름 충돌

  • spring/MemberRegisterService.java
  • spring2/MemberRegisterService.java

같은 이름으로 두 개의 클래스를 만들고 둘 모두에 @Component 애노테이션을 달아 빈으로 등록하려고 하면, ConflictingBeanDefinitionException 이 발생한다.

 

📌수동 등록한 빈과 충돌

@Configuration
public class AppCtx {

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

@Component와 @ComponentScan으로 자동 등록된 빈과 @Bean으로 수동 등록한 빈의 이름이 같은 경우, 수동 등록한 빈이 우선권을 갖는다. 즉, 위 경우 MemberDao 타입 빈은 AppCtx에서 정의한 한 개만 존재한다.

 

@Configuration
public class AppCtx {

	@Bean
	public MemberDao memberDao2() {
		MemberDao memberDao = new MemberDao();
		return new memeber;
	}
	...
}

만약 위와 같이 빈 이름은 다르게 등록하면 memberDao, memberDao2 두 개 모두 빈으로 등록된다. 그러나 같은 타입이 빈이 두 개 존재하는 것이므로 @Qualifier 애노테이션을 사용하여 알맞는 빈을 선택해야 한다.

 


1. 컴포넌트 스캔 대상에는 ( @Component ) 애노테이션을 추가한다.

2. 컴포넌트 스캔 시, 설정 클래스에는 ( @ComponentScan ) 애노테이션을 추가한다.

3. 컴포넌트 스캔 대상 애노테이션은 그 용도에 따라 세부적으로 나눌 수 있는데, 웹MVC를 이용하는 경우에는 ( @Controller ), DB 연동 이용 시에는 ( @Repository ) 를 사용할 수 있다.

4. @ComponentScan에서 스캔 대상을 필터링 하고자 하는 경우 ( includeFilters ) 와 ( excludeFilters ) 속성을 지정하면 된다.

5. 같은 이름의 빈이 컴포넌트 스캔을 통한 빈 자동 등록과 @Bean애노테이션을 이용한 빈 수동 등록 두 가지 과정 모두로 이루어진 경우에는, 둘 중 ( 수동 등록 ) 빈이 우선권을 가진다.


Spring1

EDITOR: 로자

728x90

관련글 더보기