스프링 핵심 원리 - 컴포넌트 스캔

링딩·2022년 7월 12일
0

Spring 공부

목록 보기
2/3

1. 컴포넌트 스캔

컴포넌트 스캔과 의존관계 자동 주입

  • 기존) 스프링 빈 등록시, @Bean 이나 XML의 bean 태그 등을 통해서 설정 정보에
    직접 등록할 스프링 빈을 나열
    단점) 등록해야 할 빈이 수천개가 될 수도...
    해결) '설정 정보' 없이 자동으로 스프링 빈을 등록하자 => "컴포넌트 스캔"
    그리고 의존관계 자동 주입을 위한 @Autowired

✔ 컴포넌트 스캔 사용 방법

+) @Configuration은 사실 코드 이내에 @Component 애노테이션이 붙음.
-> 그래서 컴포넌트 스캔 대상이 됨 처음에,,,

@Configuration
@ComponentScan(
 excludeFilters = @Filter(type = FilterType.ANNOTATION, classes =
Configuration.class))
//Connfiguration.class는 컴포넌트 스캔 대상에서 예외 시킴.
public class AutoAppConfig {
 
}
  • 설정 정보에 @ComponentScan 붙여서 컴포넌트 스캔 사용을 설정.
  • @Component 가 붙은 클래스들을 스캔하여 '스프링 빈'으로 등록



✔ 의존관계 자동 주입 방법

@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;
 }
}

@Autowired 사용하여 생성자에서 여러 의존관계를 한 번에 주입 받는다.




🤔컴포넌트 스캔과, 의존관계 자동 주입 과정

컴포넌트 스캔 기본 대상

컴포넌트 스캔은 @Component 뿐만 아니라 다음과 내용도 추가로 대상에 포함한다.

  • @Component : 컴포넌트 스캔에서 사용

  • @Controlller : 스프링 MVC 컨트롤러에서 사용

  • @Service : 스프링 비즈니스 로직에서 사용

  • @Repository : 스프링 데이터 접근 계층에서 사용, 컴포넌트 스캔은 @Component 뿐만 아니라 다음과 내용도 추가로 대상에 포함한다.

    +)@Configuration : 앞서 보았듯이 스프링 설정 정보로 인식하고, 스프링 빈이 싱글톤을 유지하도록 추가
    처리를 한다


---

2. 필터

* includeFilters : 컴포넌트 스캔 대상을 추가로 지정

* excludeFilters : 컴포넌트 스캔에서 제외할 대상을 지정

//컴포넌트 스캔 대상에 '추가할 애노테이션' => @MyIncludeComponent
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyIncludeComponent {
}

--

//컴포넌트 스캔 대상에 '제외할 애노테이션' => @MyExcludeComponent
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyExcludeComponent {
}

--

//컴포넌트 스캔 대상에 추가할 클래스
@MyIncludeComponent //지정한 어노테이션 설정
public class BeanA { }

--

//컴포넌트 스캔 대상에 제외할 클래스
@MyExcludeComponent //지정한 어노테이션 설정
public class BeanB { }

어디에 사용?

  • @ComponentScan()에서

  • includeFiltersMyIncludeComponent 애노테이션을 추가해서 BeanA가 스프링 빈에 등록된다.
  • excludeFiltersMyExcludeComponent 애노테이션을 추가해서 BeanB는 스프링 빈에 등록되지
    않는다.



3. 중복 등록과 충돌

: 만약 컴포넌트 스캔에서 같은 '빈' 이름이 등록된다면..?

if 1. 자동 빈 등록 vs 자동 빈 등록

  • 오류 발생 (ConflictingBeanDefinitionException 예외)

if 2. 자동 빈 등록 vs 수동 빈 등록

  • 수동 빈 등록이 우선권을 가짐

    그러나 요즘에는 이런 실수를 많이 저질러서인지...
    최근 스프링 부트에서는 '수동 빈 등록'과 '자동 빈 등록'이 충돌나면 오류가 발생하도록 기본 값을 바꿈.

[에러 메시지]

Consider renaming one of the beans or enabling overriding by setting
spring.main.allow-bean-definition-overriding=true

✔ [해결 방법]

spring.main.allow-bean-definition-overriding=true 을 application.properties에 등록하면 된다.

profile
초짜 백엔드 개린이

0개의 댓글