일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- springboot
- Web
- 一日一つメソッド
- 日本語
- Python
- nico
- ruby
- CSS
- 비즈니스일본어
- html
- 반다이몰
- Spring
- javascript
- 건담
- 単語
- rails7
- rails
- 자바
- java
- jsp
- 디지몬
- Flutter
- C로 시작하는 컴퓨터 프로그래밍4판
- メソッド
- 인프런
- 연습문제
- DART
- 건담베이스
- vscode
- 일본어
- Today
- Total
AR삽질러
Spring 컴포넌트스캔 (12) 본문
Component Scen
- ComponentScan은 spring이 클래스의 경로를 스캔하여 Spring Bean으로 등록할 클래스를 찾는 기능이다.
컴포넌트 스캔을 사용하면 수동으로 각각의 빈을 등록하지 않아도 특정 애노테이션을 가진 클래스를 자동으로 빈으로 등록하고 관리할 수 있다.
주요 애노테이션
@Component | 가장 기본적인 컴포넌드 애노테이션으로 빈을 등록할 클래스에 사용된다. |
@Controller | MVC컨트롤러로 사용되는 클래스에 사용한다. |
@Service | 서비스 로직을 담당하는 클래스에 사용한다. |
@Repository | 데이터 저장소에 접근하는 클래스 DAO(Data Access Object)에 사용한다. |
컴포넌트 스캔을 사용하려먼 @ComponentScan을 설정정보에 붙여 사용한다. 여기서 @ComponentScant은 해당 클래스의 패키지부터 하위 패키지까지 모두 스캔하게된다.
@ComponentScan은 @Component가 붙은 모든 클래스를 스프링 빈으로 등록한다.
생성자에 @Autowired를 지정하게 되면 스프링 컨테이너가 자동으로 해당 스프링 빈을 찾아 주입하게된다.
----------------------------------------------------------------------------------------------------------------------------------------------------------
1. 탐색위치와 기본스캔대상
@Configuration
@ComponentScan(
basePackages = "hello.core.member",
basePackageClasses = AutoAppConfig.class,
excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Configuration.class))
public class AutoAppConfig {
}
@ComponentScan탐색시작위치
- basePackage, basePackageClasses 두가지 속성으로 시작위치를 지정할 수 있다.
- 시작위치를 지정하지 않았을때 @ComponentScan이 붙은 설정 정보 클래스의 패키지가 시작위치가 된다.
2. ComponentScan의 기본대상 애노테이션
@Component | 기본 컴포넌트 애노테이션으로 클래스를 스프링 빈으로 등록한다. |
@Controller | 주로 웹 MVC의 컨트롤러로 사용되며 내부적으로 @Component를 포함하고 있어 스프링 빈으로 자동 등록된다. |
@Service | 비즈니스 로직을 담당하는 서비스 레이어의 컴포넌트에 주로 사용된다. |
@Repository | @데이터 저장소에 접근하는 DAO(Data Access Object)혹은 Repository레이어 컴포넌트에 사용된다. |
@Configuration | 스프링 설정정보를 담고 있는 클래스에서 사용되며 @Bean과 함께 사용되어 스프링 컨테이너에 빈 객체를 등록한다. |
3. Filter
필터를 통해서 원하는 타입의 컴포넌트만 스캔하거나 특정 컴포넌트를 제외하는 필터링 기능을 사용할 수 있다.
1) includeFilters
- 스캔 대상 중에서 특정 조건에 맞는 컴포넌트만 스캔 대상으로 포함하고자 할때 사용한다.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyIncludeComponent {
}
2) excludeFilters
- 스캔 대상 중에서 특정 조건에 맞는 컴포넌트를 스캔 대상에서 제외하고자 할때 사용한다.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyExcludeComponent {
}
@MyIncludeComponent
public class BeanA {
}
@MyExcludeComponent
public class BeanB {
}
public class ComponentFilterAppConfigTest {
@Test
void filterScan() {
ApplicationContext ac = new
AnnotationConfigApplicationContext(ComponentFilterAppConfig.class);
BeanA beanA = ac.getBean("beanA", BeanA.class);
assertThat(beanA).isNotNull();
Assertions.assertThrows(
NoSuchBeanDefinitionException.class,
() -> ac.getBean("beanB", BeanB.class));
}
@Configuration
@ComponentScan(
includeFilters = @Filter(type = FilterType.ANNOTATION, classes =
MyIncludeComponent.class),
excludeFilters = @Filter(type = FilterType.ANNOTATION, classes =
MyExcludeComponent.class)
)
static class ComponentFilterAppConfig {
}
}
MyIncludeComponent : BeanA : 컴포넌트 스캔대상에 포함
MyExcludeComponent : BeanB : 컴포넌트 스캔대상에서 제외
includeFilters : @MyIncludeCompoent 애노테이션이 붙은 컴포넌트만 스캔 대상에 포함한다고 지정
excludeFilters : @MyExcludeCompoent 애노테이션이 붙은 컴포넌트만 스캔 대상에 제외한다고 지정
ComponentFilterAppConfigTest Class
- filterScan() 테스트 메서드를 이용해 spring container에서 BeanA는 존재하고 BeanB는 존재하지 않다는것을 검증한다.
FilterType Option
ANNOTAION | 지정된 애노테이션 타입에 의해 지정된 컴포넌트를 포함하거나 제외한다. | org.example.SomeAnnotaion |
ASSIGNABLE_TYPE | 지정된 타입 또는 그 하위 타입의 컴포넌트를 포함하거나 제외한다. | org.example.SomeClass |
ASPECTJ | AspectJ패턴 표현식을 사용하여 컴포넌트를 포함하거나 제외한다. | org.example..*Service+ |
REGEX | 정규 표현식을 사용하여 컴포넌트를 포함하거나 제외한다. | org.example\/Default.* |
CUSTOM | 사용자 지정 TypeFilter 구현을 사용하여 컴포넌트를 포함하거나 제외한다. | org.example.MyTypeFilter |
결론 : @Component으로 충분하기 때문에 includeFilters를 사용할 일은 없지만 excludeFilters는 간혹 사용할 일이 있다.
----------------------------------------------------------------------------------------------------------------------------------------------------------
4. 중복 등록과 충돌
1) 자동 빈 등록 vs 수동 빈 등록
- 스프링 컨테이너는 @Component를 사용하여 빈을 자동으로 등록하지만 @Bean 애노테이션을 사용하여 Java설정파일에서 수동으로 빈을 등록할 수 도 있다.
2) 자동 빈 등록 vs 자동 빈 등록
- 컴포넌트 스캔에 의해 자동으로 스프링 빈이 등록되지만 등록된 빈의 이름이 같은 경우 스프링 요류가 발생한다.
* ConflictingBeanDefinitionException 예외 발생
해결방법
- 빈이름 변경
- 수동 빈 등록
- 특정 패키지 제외
- 명시적인 충돌 해결
3) 수동 빈 등록 vs 자동 빈 등록
'JAVA > Spring' 카테고리의 다른 글
Spring 의존관계자동주입 - 의존관계주입방법(13) (0) | 2023.08.21 |
---|---|
Spring Singleton, SingletionContainer (11) (0) | 2023.08.05 |
Spring BeenFactory와 ApplicationContext(10) (0) | 2023.08.04 |
Spring Been 조회 - 상속관계(9) (0) | 2023.07.16 |
Spring springBeen조회(8) (0) | 2023.07.16 |