컴포넌트 스캔은 스프링이 직접 클래스를 검색해서 빈으로 등록해주는 기능이다. 설정 클래스에 빈으로 등록하지 않아도 원하는 클래스를 빈으로 등록할 수 있다. 이 기능을 사용하면 설정 코드가 줄어든다.
📌 순서
- @Component
- @ComponentScan
- 기본 컴포넌트 스캔 대상
@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로 빈 이름을 지정하여 만들도록 한다.
@Component 애노테이션을 붙인 클래스를 스캔해서 빈으로 등록하기 위해서는 설정 클래스에 @ComponentScan 애노테이션이 필요하다.
basePackages
속성 값을 이용해 스캔 대상을 지정한다.
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 프로그래밍 입문 | 최범균님 저