쌓고 쌓다

컴포넌트 스캔과 의존관계 주입 본문

프로그래밍/spring

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

승민아 2023. 7. 13. 15:48

컴포넌트 스캔

스프링은 설정 정보가 없어도 스프링 빈을 자동으로 등록해주는 "컴포넌트 스캔"을 제공한다.

 

AutoAppConfig

@Configuration
@ComponentScan
public class AutoAppConfig {

}

설정 정보라 @Configuration 써주고,

스프링 빈을 등록하기위해 어노테이션이 부여된 클래스를 자동으로 IoC컨테이너에 등록하기위해 @ComponentScan 작성한다.

 

+ 컴포넌트 스캔 대상에서 제외

@ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Configuration.class))

 

컴포넌트 스캔이 기존의 에제 코드에 사용된 @Configuration이 붙은 설정 정보도 자동 등록하기에 ( 왜냐 안에 @Component가 있음 )

excludeFilters를 통해 제외할 수 있다.

 

컴포넌트 스캔 대상 등록

@ComponentScan은 @Component가 붙은 클래스를 찾아 빈으로 등록해준다.

 

MemoryMemberRepository

@Component
public class MemoryMemberRepository implements MemberRepository {
    ...
}

@Component 어노테이션을 붙여줌으로써 컴포넌트 스캔 대상으로 등록할 수 있다.

 

 

아니!?? 스프링 빈 등록을 위해 @Component를 써주는건 알겠다.

근데 의존관계는 어떻게 등록해줄건데!??

의존 관계를 자동 주입해주는 어노테이션을 함께 사용한다!

바로 "@Autowired"이다..!

 

MemberServiceImpl

@Component
public class MemberServiceImpl implements MemberService{

    private final MemberRepository memberRepository;

    @Autowired
    public MemberServiceImpl(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }
}

 

 

아니!?!?!? 어떻게 의존관계를 자동으로 주입해준다는건데???

"MemberRepository"의 타입이 맞는 것을 찾아와서 의존관계 주입을 자동으로 해준다.

쉽게 ac.getBean(MemberRepository.class)로 동작을 한다고 이해하자.

 

아니!?!?!?!!??!?!?!? 선생님 타입이 여러개 존재하면 어떻게 알아서 찾아줄까요?

충돌이 일어난다고한다.

 

컴포넌트 스캔 대상

아래의 어노테이션이 붙은 클래스 또한 컴포넌트 스캔 대상이 된다. 왜냐 이 어노테이션 안에 @Component가 들어있다.

  • @Controller
  • @Service
  • @Repository
  • @Configuration

 

컴포넌트 스캔 위치

package hello.springstudy;

@Configuration
@ComponentScan
public class AutoAppConfig {

}

기본 설정 값으로 hello.springstudy의 하위 패키지들을 뒤지면서 탐색한다.

그래서 AutoAppConfig와 같은 프로젝트 설정은 프로젝트 시작 루트에 둔다.

 

 

 

 

스프링 빈으로 잘 등록하는지 테스트 코드를 작성해보자.

 

AutoAppConfigTest

public class AutoAppConfigTest {

    @Test
    void basicScan() {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class);

        MemberService memberService = ac.getBean(MemberService.class);

        Assertions.assertThat(memberService).isInstanceOf(MemberService.class);
    }
}

사용 방법은 기존의 AnnotationConfigApplicationContext와 동일하다.

 

스프링 컨테이너 상태

출처: 인프런 - 김영한

스프링 빈 이름은

클래스 이름으로 사용하지만, 첫글자는 소문자로 한다.

 

스프링 빈 이름을 내가 정하고싶다면? 아래와 같이 어노테이션을 작성하자.

@Component("이름")

 

의존관계 자동 주입

출처 : 인프런 - 김영한

생성자의 @Autowired로 의존관계 자동 주입을 하는데

ac.getBean(MemberRepository.class)와 같이 맞는 타입의 빈을 스프링 컨테이너에서 찾아 주입해준다.

Comments