컴포넌트 스캔

정의정·2023년 7월 6일
0

Spring

목록 보기
11/12
post-thumbnail

💡 컴포넌트 스캔

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

📌 순서

  1. @Component
  2. @ComponentScan
  3. 기본 컴포넌트 스캔 대상

🌟 @Component

@Component 애노테이션은 해당 클래스를 스캔 대상으로 표시한다.

1. Component 사용

MemberDao에 @Component 애노테이션을 사용한 예다.

MemberDao.java에 @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);
	}

	public void insert(Member member) {
		member.setId(++nextId);
		map.put(member.getEmail(), member);
	}

	public void update(Member member) {
		map.put(member.getEmail(), member);
	}
	
	public Collection<Member> selectAll() {
		return map.values();
	}

}

@Component 애노테이션에 속성 값을 설정하면, 빈 이름을 지정할 수 있다.

@Component 애노테이션에 속성 값 설정✔️

@Component("mDao")

ChangePasswordService, MemberDao, MemberInfoPrinter, MemberListPrinter, MemberRegisterService 클래스에 @Component 애노테이션을 붙여보자.

@Component 애노테이션의 속성 값을 이용하여 MemberInfoPrinter는 infoPrinter, MemberListPrinter는 listPrinter로 빈 이름을 지정하여 만들도록 한다.


🌟 @ComponentScan

@Component 애노테이션을 붙인 클래스를 스캔해서 빈으로 등록하기 위해서는 설정 클래스에 @ComponentScan 애노테이션이 필요하다. basePackages 속성 값을 이용해 스캔 대상을 지정한다.

1. AppCtx 설정 클래스에 적용

App.Ctx에 @ComponentScan 적용

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

	@Bean
	@Qualifier("printer")
	public MemberPrinter memberPrinter1() {
		return new MemberPrinter();
	}

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

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

확실히 설정 코드가 줄어든 것을 확인할 수 있다.

이제 변경된 코드를 메인 클래스 MainForSpring에 반영시켜야 한다.

MainForSpring.java 수정✏️

MemberRegisterService regSvc = ctx.getBean(MemberRegisterService.class);

ChangePasswordService changePwdSvc = ctx.getBean(ChangePasswordService.class);

processNewCommand(), processChangeCommand() 메서드에서 빈을 검색하는 부분을 위처럼 타입만으로 구하도록 변경하면 된다.

🌟 기본 컴포넌트 스캔 대상

@Component 애노테이션 외에도 컴포넌트로 스캔되는 대상이 여럿 있다.

<기본 스캔 대상>

👉🏻 @Component
👉🏻 @Controller
👉🏻 @Service
👉🏻 @Repository
👉🏻 @Aspect
👉🏻 @Configuration

@Aspect 애노테이션을 제외하고는 모두 @Component 애노테이션에 대한 특수 애노테이션이다. 각각 언제 쓰이는 애노테이션인지는 차차 다루기로 한다.

🎀 줄이며...

이번엔 컴포넌트 스캔에 대한 내용을 다뤘다. @component, @ComponentScan 애노테이션을 사용함으로써 설정 클래스의 코드를 크게 줄일 수 있었다.

빈 이름 중복이나, @Bean 애노테이션을 사용해 수동 등록한 빈과의 따른 충돌이 일어날 수 있다.

  • 스캔 범위 내에 같은 빈 이름을 가지는 클래스가 둘 이상인 경우 익셉션이 발생한다.
  • 수동 등록한 빈과 컴포넌트 스캔으로 등록된 빈이 중복되는 경우 수동 등록한 빈이 우선한다.

위 사항을 유의하여 사용하면 좋을 것 같다.

📖 교재 및 출처

  • 초보 웹 개발자를 위한 스프링5 프로그래밍 입문 | 최범균님 저
profile
배움 기록

0개의 댓글