컴포넌트 스캔

이원석·2022년 1월 24일

Spring

목록 보기
6/20
post-thumbnail
*인프런 김영한 강사님의 강좌를 참고하여 정리한 내용입니다.*

스프링 컨테이너에 빈을 등록하는 방법


지금까지 스프링 빈을 등록하기 위해서는 자바 코드의 @Bean을 활용하거나 XML의 <bean> 을 통하여 설정 정보에 직접 스프링 빈을 등록했다!

그런데..

만약 등록해야 할 스프링 빈이 수십, 수백개가 되면 일일이 등록하기 힘들며 설정 정보가 커짐에 따라 누락할 수 있는 가능성도 생긴다!

그래서 스프링은 설정 정보가 없어도 자동으로 스프링 빈을 등록하는 컴포넌트 스캔이라는 기능을 제공하며 자동 의존관계 주입을 해주는 @Autowired 라는 기능도 제공한다.

@Configuration는 자동으로 컴포넌트 스캔의 대상이 되는데, 구체적인 소스코드를 확인해보면 이미 @Component 애노테이션이 붙어있다.





@ComponentScan과 @Autowired


<기존의 스프링 빈 등록방식>

@Configuration
public class AppConfig {

	@Bean
    public MemberSerivce memberService() {
    ...


<@ComponentScan과 @Autowired를 활용한 스프링 빈 등록방식>

1. 구성정보를 서칭하는 클래스

@Configuration
@ComponentScan
public class AppConfig {
}

2. @Bean으로 등록되었던 메서드들의 각 클래스들에 @Component를 붙여준다.

@Component
public class MemberServiceImpl implements MemberService {
	...
@Component
public class MemoryMemberRepository implements MemberRepository {
	...
@Component
public class RateDiscountPolicy implements DiscountPolicy {
	...

등등..


3. 의존관계 주입이 필요한 클래스에는 @Autowired를 활용한다.

@Component
public class MemberServiceImpl implements MemberService {
	
    // 인터페이스에 의존하며 어떤 구현체가 주입될지는 모른다! (DIP 의존관계 역전 원칙)
    private final MemberRepository memberRepository;
    
    // 생성자의 type에 따라 스프링 컨테이너에 등록된 같은 타입의 클래스를 자동으로 의존관계 주입해준다.
    @Autowired
    public MemberServiceImpl(MemberRepository memberRepository) {
    	this.memberRepository = memberRepository;
    }

기존의 방식에서는 @Bean으로 직접 설정정보를 작성했고, 의존관계도 명시했지만 이제는 설정정보 자체가 없기 때문에 의존관계 주입도 클래스 안에서 해결해야 한다.





동작과정


1. @ComponentScan

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

@Bean과 같이 @Component("xxx")로 빈 이름을 부여할 수 있다!


2. @Autowired

@Component 클래스의 생성자에 @Autowired를 지정하면, 스프링 컨테이너가 자동으로 해당 스프링 빈을 찾아서 주입한다. (타입이 같은 빈을 찾아서 주입한다)

스프링 빈 컨테이너의 memoryMemberRepository는 MemberRepository를 상속받고 있기 때문에 파라미터의 MemberRepository와 같은 타입이다. DiscountPolicy도 마찬가지





컴포넌트 스캔의 탐색위치와 기본 스캔 대상


모든 자바 클래스를 다 컴포넌트 스캔하면 시간이 오래걸릴 수 있다. 따라서 꼭 필요한 위치부터 탐색하도록 시작 위치를 설정할 수 있다.

basePackges

@ComponentScan {
	basePackages = "hello.core",
}

탐색할 패키지의 시작 위치를 지정하며 이 패키지를 포함해서 하위 패키지를 모두 탐색한다. 여러개의 패키지 시작 위치를 지정할 수도있다.

basePackageClasses

@ComponentScan {
	basePackagesClasses = AppConfig.class,
}

지정한 클래스의 패키지를 탐색 시작 위치로 지정한다. AppConfig가 hello.core패키지에 포함되어있다면 해당 패키지를 탐색 시작 위치로 지정한다.

탐색위치의 Default값은 @ComponentScan이 붙은 설정 정보 클래스의 패키지가 시작 위치가 된다.

프로젝트 메인 설정 정보는 프로젝트를 대표하는 정보이기 때문에 프로젝트 시작 루트 위치에 두는것이 좋다. 따라서 패키지 위치를 따로 지정하지 않고, 설정 정보 클래스의 위치를 프로젝트 최상단에 두는 방법을 권장한다고 한다!

스프링 부트를 사용하면 대표 시작 정보인 @SpringBootApplication을 프로젝트 시작 루트 위치에 두는것이 관례라고 한다. @SpringBootApplication에는 @ComponentScan이 들어있다!



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

  • @Component: 컴포넌트 스캔에서 사용
  • @Controller: 스프링MVC 컨트롤러에서 사용
  • @Service: 스프링 비지니스 로직에서 사용
  • @Repository: 스프링 데이터 접근 계층에서 사용
  • @Configuration: 스프링 설정 정보에서 사용


0개의 댓글