이 프로젝트의 개발 환경
- 개발 언어 및 개발 환경
- OpenJDK 12
- Spring: spring-context 5.0.2.RELEASE
- Gradle 7.3
- 기타 환경
- macOS Sonoma 14.1.1
- IntelliJ IDEA 2020.3 Ultimate Edition
예제에 앞서 이 블로그의 문서: Chapter 04. 자동 의존 주입을 선행합니다.
컴포넌트 스캔은 자동 의존 주입과 함께 사용하는 기능입니다. 스프링이 직접 클래스를 검색해서 Bean으로 등록하도록 합니다.
설정 클래스에서 Bean으로 등록하지 않아도 되므로 컴포넌트 스캔을 사용하면 설정 코드가 확연히 줄어듭니다.
예제 프로젝트 생성
sp5-chap05 프로젝트를 생성하고 chap05 패키지를 추가합니다.
이전 프로젝트의 chap04 패키지의 소스 파일을 복사하여 사용합니다.
$ tree
.
├── build.gradle
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── src
└── main
├── java
│ └── chap05
│ ├── AppContext.java
│ ├── ChangePasswordService.java
│ ├── Main.java
│ ├── Member.java
│ ├── MemberDao.java
│ ├── MemberInfoPrinter.java
│ ├── MemberListPrinter.java
│ ├── MemberPrinter.java
│ ├── MemberRegisterService.java
│ ├── MemberSummaryPrinter.java
│ └── RegisterRequest.java
└── resources
7 directories, 16 files
@Component으로 스캔 대상 지정
@Component 어노테이션이 등록된 클래스는 Spring의 스캔 대상이 됩니다.
기존 소스 파일에서 다음 클래스에 @Component를 등록합니다.
@Component
public class MemberDao { }
@ComponentScan
public class ChangePasswordService { }
@ComponentScan
public class MemberRegisterService { }
@Component("infoPrinter")
public class MemberInfoPrinter { }
@ComponentScan("listPrinter")
public class MemberListPrinter { }
코드 | 비고 | |
클래스를 스캔 대상으로 지정합니다. | ||
클래스를 스캔 대상으로 지정합니다. 어노테이션에서 지정하는 |
||
클래스를 스캔 대상으로 지정합니다. 어노테이션에서 지정하는 |
@ComponentScan으로 스캔 설정
@Component 어노테이션이 등록된 클래스를 Bean으로 등록하려면 설정 클래스에서 @ComponentScan을 적용해야 합니다.
설정 클래스 AppContext를 다음과 같이 수정합니다.
package chap05;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = {"chap05"})
public class AppContext
{
@Bean
public MemberPrinter memberPrinter()
{
return new MemberPrinter();
}
@Bean
public MemberSummaryPrinter memberPrinterSeconds()
{
return new MemberSummaryPrinter();
}
}
코드 | 비고 | |
설정 클래스에서 컴포넌트 스캔을 활성화합니다. 어노테이션이 지정하는 |
||
컴포넌트 스캔 대상이 아닌 나머지 클래스를 Bean으로 등록합니다. 이제 컴포넌트 스캔 대상은 설정 클래스에서 관리하지 않습니다. |
Main 클래스에서는 Bean 객체에 접근하는 코드는 다음과 같습니다.
ctx.getBean(MemberRegisterService.class);
ctx.getBean(ChangePasswordService.class);
ctx.getBean("listPrinter", MemberListPrinter.class);
ctx.getBean("infoPrinter", MemberInfoPrinter.class);
코드 | 비고 | |
컴포넌트 스캔으로 등록된 Bean 객체에 접근합니다. |
||
컴포넌트 스캔으로 등록된 Bean 객체에 접근합니다. |
||
애플리케이션을 실행하고 명령문을 실행합니다. Bean 객체에 정상적으로 엑세스하고 있는지 확인합니다.
Bean이 제대로 등록되지 않았다면 No bean named '<Bean 이름>' available 오류가 발생합니다.
스캔 대상은 다음 어노테이션이 등록된 클래스입니다.
어노테이션 | FQCN(Full Qualified Class Name) |
스캔 대상에서 제외하기 위한 excludeFilters 옵션
excludeFilters 속성을 사용해 스캔 대상을 제외 할 수 있습니다.
스캔에서 제외하기 위한 ExcludedMemberDao 클래스를 생성하고 @Component를 등록합니다.
그리고 AppContext의 @ComponentScan을 다음과 같이 수정합니다.
@Configuration
@ComponentScan(basePackages = {"chap05"}, excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = "chap05\\..*ExcludedMemberDao"))
public class AppContext
{
}
코드 | 비고 | |
자동으로 스캔되는 대상을 제외합니다. | ||
정규표현식을 사용해서 제외 대상을 지정합니다. | ||
특정 어노테이션이 등록된 클래스를 스캔 대상에서 제외 할 수 있습니다.
ExcludedMemberDao 클래스에 @NoProduct 어노테이션을 등록하고 AppContext를 다음과 같이 수정합니다.
@Configuration
@ComponentScan(basePackages = {"chap05"}, excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = { NoProduct.class }))
public class AppContext
{
}
코드 | 비고 | |
어노테이션이 등록된 대상을 제외합니다. | ||
특정 타입이나 그 하위 타입을 스캔 대상에서 제외 할 수 있습니다.
@Configuration
@ComponentScan(basePackages = {"chap05"}, excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = ExcludedMemberDao.class))
public class AppContext
{
}
코드 | 비고 | |
특정 타입인나 그 하위 타입을 대상에서 제외합니다. | ||
스캔 제외 대상 필터를 여러 개 등록하려면 excludeFilters 옵션을 배열로 사용합니다.
@Configuration
@ComponentScan(basePackages = {"chap05"}, excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = { NoProduct.class }),
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = ExcludedMemberDao.class)
})
public class AppContext
{
}
정리 및 복습
- 컴포넌트 스캔을 사용하면
스프링이 직접 클래스를 검색해서 Bean으로 등록하도록 합니다. - 스캔 대상이 되는 클래스는
@Component어노테이션을 등록합니다. - @Component의
value옵션에서Bean 이름을 지정할 수 있습니다. - 설정 클래스에서
@ComponentScan을 등록해 컴포넌트 스캔을 수행합니다. - @ComponentScan의
basePackages옵션에서스캔 대상을 검색하기 위한 패키지 경로를 지정합니다. - @ComponentScan의
excludedFilters옵션에서스캔 대상에서 제외하기 위한 필터를 지정합니다.
타입 | 비고 | 예시 |
'Java > Spring' 카테고리의 다른 글
Spring 5 입문: Chapter 06. Bean 라이프사이클과 범위 (0) | 2023.11.28 |
---|---|
"NoSuchBeanDefinitionException" Bean과 관련해서 자주 발생하는 오류 (0) | 2023.11.28 |
자동 의존 주입을 위한 @Autowired @Resource @Inject 차이 (0) | 2023.11.27 |
Spring 5 입문: Chapter 04. 자동 의존 주입 (0) | 2023.11.27 |
@Configuration 어노테이션 개념과 특징 (0) | 2023.11.23 |