관리 메뉴

공부 기록장 💻

[Spring] 컴포넌트 스캔과 의존관계 자동 주입 (@ComponentScan, @Autowired) 본문

# Tech Studies/Java Spring • Boot

[Spring] 컴포넌트 스캔과 의존관계 자동 주입 (@ComponentScan, @Autowired)

dream_for 2023. 2. 2. 09:25

인프런 - 스프링 핵심 원리 기본편 정리


지금까지 스프링 컨테이너를 생성하고, 구성 정보 AppConfig를 통해 객체들을 스프링 빈으로 등록하는 방법에 대해 배웠다. 그리고 스프링 컨테이너가 스프링 빈을 싱글톤으로 관리한다는 것 또한 이해하였다.

이번에는 스프링 빈을 직접 등록하지 않고, 스프링 컨테이너가 자동으로 스프링 빈을 등록하고, 의존 관계를 자동적으로 주입하도록 하는 컴포넌트 스캔에 대해 학습해보자.

 

 

 

직접 스프링 빈을 등록하는 방법 2가지 - @Bean과  xml 방식

기존에 스프링 빈을 등록하는 방법으로 다음의 두 가지를 학습하였다.

1. AppConfig에서 객체를 생성하는 메서드 위에 @Bean 어노테이션을 추가하는 방식
2. XML 파일에서 <bean> 작성하는 방식

 

두 방법 모두 코드를 통해 각 객체를 직접 설정 정보를 통해 직접 스프링 빈을 등록하는 방식이다. 그러나 등록해야 할 스프링 빈이 수십, 수백 개가 되는 경우에는 위의 방식을 이용해 일일히 스프링 빈으로 등록하기가 매우 번거로워진다.

 

 

자동으로 스프링 빈을 등록하는 컴포넌트 스캔

@ComponentScan, @Component, @Autowired

따라서 스프링은 설정 정보가 없어도, 자동으로 스프링 빈을 등록하는 컴포넌트 스캔이라는 기능을 제공한다. 

이를 간단하게 설명하면, 기존과 같이 AppConfig에서 직접 @Bean으로 설정 정보를 작성하고, 의존 관계를 직접 명시하는 방법이 아니라
@ComponentScan@Component, @Autowired를 통한 의존 관계를 자동으로 주입하는 기능이다.

 

AutoAppConfig 클래스

기존에 만들었던 AppConfig는 남겨두고, AutoAppConfig 클래스를 만들어보자.

설정 정보를 나타내는 클래스임을 명시하기 위해 @Configuration 어노테이션을 작성하고, 추가적으로 자동 컴포넌트 스캔을 사용하기 위해 @ComponentScan 를 작성하자.

컴포넌트 스캔은 @Component 애노테이션이 붙은 클래스들을 자동으로 스캔하여 스프링 빈으로 등록한다

(기존의 AppConfig를 이용한 설정 정보는 제외시키기 위해 excludeFilters를 사용했다.)

 

 


이제 컴포넌트 대상이 되는 구현체 클래스들 위에 @Component 애노테이션을 추가하자. 

(여기서 컴포넌트 대상은, MemoryMemberRepository, RatedDiscoutPolicy, MemberServiceImpl, OrderServiceImpl 구현체 클래스들이 된다.)

 

우리가 사용하고자 하는 구현체 클래스 위에 @Component 어노테이션을, 그리고 생성자 위에는 @Autowired를 추가하자. 1) @Component를 붙여 스프링 빈으로 등록하고, 2) 생성자의 @Autowired를 통해 필요한 구현체의 의존 관계를 자동적으로 주입해주는 역할을 한다.

@Autowired는 ApplicationContext(스프링 컨테이너)의 getBean()을 이용해 필요한 구현체 클래스를 스프링 컨테이너에 스프링 빈으로 등록하거나, 또는 등록되어 있는 스프링 빈을 가져 오는 것이라 할 수 있다. (이 글에서 작성했던 스프링 컨테이너 참조)

 

1) MemoryMemberRepository

 

 

2) RatedDiscountPolicy

 

 

3) MemberServiceImpl

 

 

4) OrderServiceImpl

 

 

 

테스트 (AutoAppConfigTest)

이제 위에서 작성한 AutoAppConfig를 통한 컴포넌트 스캔이 잘 작동하는지 테스트 케이스를 작성해보자.

ApplicationContext를 통해 스프링 컨테이너 객체 ac를 생성하고, AutoAppConfig 클래스를 설정 정보를 사용하자.

스프링 컨테이너에 스프링 빈으로 등록되어 있는 MemberService 객체를 가져와 MemberService 클래스의 객체가 맞는지 검증해보도록 하자.

 

 

위의 테스트는 성공적으로 수행된다. 이제 로그를 확인하여 컴포넌트 스캔이 자동적으로 작동되었는지 확인해보자.

 

 

로그 확인

로그를 자세히 확인해보면, 1) 컴포넌트 스캔,  2) 싱글톤 빈 인스턴스 생성, 3) autowiring을 통한 의존 관계 주입의 과정을 모두 확인할 수 있다. 로그 내용은 다음과 같다. 

 

 

1) Identified candidate component class  (컴포넌트 스캔 후보 클래스 발견)

  • RatedDiscountPolicy, MemberServiceImpl, MemoryMemberRepository, OrderServiceImpl)

2) Creating shared instance of singleton bean (싱글톤 빈의 공유되는 인스턴스 생성)

  • autoAppconfig, ratedDiscountPolicy, memberServiceImpl, memoryMemberRepository )

3) Autowiring by type from bean name '생성된 빈 이름' via constructor to bean named '생성자를 통해 주입된 빈 이름'

  • memberService via memoryMemberRepository
  • orderServiceImpl via memoryMemberRepository
  • orderServiceImpl via ratedDiscountPolicy)

 

 


 

컴포넌트 스캔과 자동 의존관계 주입의 과정을 그림으로 다시 한 번 이해해보자.

 

1. @ComponentScan

@Component가 붙은 모든 클래스를 스프링 빈으로 등록한다.

  • 스프링 빈의 기본 이름은 클래스명을 사용하되, 맨 앞글자만 소문자를 사용하여 빈 이름을 등록한다.
    • 빈 이름 기본 전략: MemberServiceImpl 객체의 경우, 빈 이름은 memberServiceImp 로 등록된다.
  • 빈 이름을 직접 지정하고자 하는경우, @Component("이름") 과 직접 이름을 작성하면 된다.

 

 

2. @Autowired 의존관계 자동 주입

생성자에 @Autowired를 지정하면, 스프링 컨테이너가 자동으로 해당 스프링 빈을 찾아 주입한다.

  • 기본 조회 전략타입이 같은 빈을 찾아 주입하는 방식이다. 
  • getBean(MemberRepository.class) 와 동일하다고 이해하자.

728x90
반응형
Comments