728x90
6.컴포넌트 스캔
- 목차
- 1.컴포넌트 스캔과 의존관계 자동주입 시작
- 2.탐색위치와 기본 스캔대상
- 3.필터
- 4.중복 등록과 충돌
1.컴포넌트 스캔과 의존관계 자동주입 시작
- 스프링 빈등록할때는 자바코드의 @Bean , xml 의
설정을 했다 - 하지만 이렇게 등록해야되는 빈이 많다면 ? 귀찮고 누락되는 일도 많아진다
- 스프링 설정정보가 없어도 자동으로 등록해주는 컴포넌트 스캔등장
- Autowired 라는 의존관계도 자동으로 주입하는 기능도 필요하다
AutoAppConfig.java
@Configuration
@ComponentScan(
excludeFilters = @Filter(type = FilterType.ANNOTATION, classes =
Configuration.class))
public class AutoAppConfig {
}
- @ComponentScan 을 사용해서 컴포넌트 스캔을 이용
- AutoAppConfig 는 @Bean 동록한게 없다
- @Configuration 도 안에 @Component 가 있어서 자동으로 등록되기때문에 excludeFilters 을써서 지워준다
- 타입 - ANNOTATION , classes - Configuration
MemoryMemberRepository
@Component
public class MemoryMemberRepository implements MemberRepository {}
- MemoryMemberRepository 에 @Component 붙여준다
RateDiscountPolicy
@Component
public class RateDiscountPolicy implements DiscountPolicy {}
- RateDiscountPolicy 에 @Component 붙여준다
MemberServiceImpl
@Component
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberServiceImpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
- 기존 AppConfig 와 달리 의존관계를 직접 등록해야된다
- 생성자에 @Autowired 붙여서 자동으로 주입하게 해준다
OrderServiceImpl
@Component
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy
discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
AutoAppConfigTest
public class AutoAppConfigTest {
@Test
void basicScan(){
AnnotationConfigApplicationContext ac =new AnnotationConfigApplicationContext(AutoAppConfig.class);
MemberService memberService = ac.getBean(MemberService.class);
assertThat(memberService).isInstanceOf(MemberService.class);
}
}
- 아까만든 AutoAppConfig 를 스프링에 등록한다
- 정상적으로 빈이 컴포넌트 스캔으로 자동으로 등록된것을 볼수 있다
2.탐색위치와 기본 스캔대상
- 모든 자바클래스를 다 컴포넌트 스캔하면 시간이 오래걸린다
- 필요한 위치부터 탐색하도록 시작위치를 지정할수 있다
AutoAppConfig
@Configuration
@ComponentScan(
basePackages = "hello.Study_Spring.member",
basePackageClasses = AutoAppConfig.class,
excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = Configuration.class)
)
public class AutoAppConfig {
}
- basePackages 를 이용해서 컴포넌트 스캔을 지정할수 있다
- basePackages 는 여러개를 지정할수 있다
- basePackageClasses 를 이용해서 클래스도 지정할수 있다
- basePackages , basePackageClasses 지정하지 않을 경우 hello.Study_Spring 의 하위 패키지부터 찾는다
참고
- @SpringBootApplication 는 기본적으로 @ComponentScan 이 있다
- 스프링부트를 쓰면 자동으로 컴포넌트를 스캔해서 빈이 등록된다
컴포넌트 스캔 기본대상
@Component
public @interface Controller {
}
@Component
public @interface Service {
}
@Component
public @interface Configuration {
}
- @Component : 컴포넌트 스캔 사용
- @Controller : 스프링 MVC 컨트롤러
- @Service : 스프링 비즈니스 로직에서 사용
- @Repository : 스프링 데이터 접근계층에서 사용 (데이터계층의 예외를 스프링 예외로 변환)
- @Configuration : 스프링 설정 정보에서 사용 (스프링 빈이 싱글톤을 유지하도록 해줌)
3.필터
- includeFilters : 컴포넌트 스캔 대상추가
- excludeFilters : 컴포넌트 스캔에서 제외
컴포넌트 스캔대상에 추가할 어노테이션
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyIncludeComponent {
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyExcludeComponent {
}
스캔대상에 추가할 클래스 및 제외할 클래스
@MyIncludeComponent
public class BeanA {
}
@MyExcludeComponent
public class BeanB {
}
- BeanA : 추가
- BeanB : 제외
스캔대상에 추가할 클래스 및 제외할 클래스
public class ComponentFilterAppConfigTest {
@Test
void filterScan(){
AnnotationConfigApplicationContext 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 = @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = MyIncludeComponent.class),
excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = MyExcludeComponent.class)
)
static class ComponentFilterAppConfig{}
}
정리
- @Component 충분
- 스프링부트는 컴포넌트 스캔을 기본으로 제공하기 때문에 스프링 기본설정에 맞추어서 사용하자
4.중복 등록과 충돌
- 자동빈 등록 vs 자동빈 등록
- 수동빈 등록 vs 자동빈 등록
수동빈 등록 vs 자동빈 등록
- 기존에는 수동빈이 우선권을 가진다 (오버라이딩)
- 스프링 부트사용시 둘다 오류메시지를 날린다
참고
728x90
'Back-End > Spring' 카테고리의 다른 글
7.의존관계 자동주입 (0) | 2021.01.11 |
---|---|
5.싱글톤 컨테이너 (0) | 2021.01.05 |
4.스프링 컨테이너와 스프링 빈 (0) | 2021.01.04 |
3.스프링 핵심 원리 이해2 - 객체지향원리적용 (0) | 2021.01.01 |
2.스프링 핵심 원리 이해1 - 예제만들기 (0) | 2020.12.31 |