해당 포스트는 초보 웹 개발자를 위한 스프링 5 프로그래밍 입문 [최범균 저] 책 내용을 참고하였습니다.
1. MemberDao(→memberDao), ChangePasswordService(→changePasswordService), MemberRegisterService(→memberRegisterService)
@Component
public class MemberDao {
...
}
2. MemberInfoPrinter(→infoPrinter), MemberListPrinter(→listPrinter)
@Component("infoPrinter")
public class MemberInfoPrinter {
...
}
설정 클래스에 @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(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); //
...
}
}
같은 이름으로 두 개의 클래스를 만들고 둘 모두에 @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: 로자
[스프링1] 7장. AOP 프로그래밍 (0) | 2022.11.10 |
---|---|
[스프링1] 6장. 빈 라이프 사이클과 범위 (0) | 2022.11.05 |
[스프링1] 4장. 의존 자동 주입 (0) | 2022.11.05 |
[스프링 1] 3장.스프링 DI (0) | 2022.10.27 |
[스프링 1] 2장.스프링 시작하기 (0) | 2022.10.27 |