@ComponentScan 을 통해 빈 등록을 위한 컴포넌트 스캔을 조작할 수 있다.

 

basePackages 옵션을 통해 컴포넌트 스캔을 시작할 패키지의 위치를 직접 설정할 수 있으나 디폴트는 일단 @Component 가 있는 클래스가 속한 패키지를 시작으로 그 하위를 모두 스캔한다.

 

일반적이고 바람직한 방식은 스캔 시작 패키지를 따로 지정하기 보다는 설정 정보 클래스(AppConfig)를 프로젝트 최상단에 두는 것이다.

 

프로젝트의 구조가 다음과 같다면,

com.hello

com.hello.service

com.hello.repository

AppConfig를 com.hello 하위에 만들고 @ComponentScan을 다는 것이다. 그럼 service, repository 모든 패키지를 스캔할 수 있다.

 

컴포넌트 스캔을 시작하면 스캔 범위에 해당하는 모든 클래스를 검사하여 @Component 가 붙은 모든 클래스의 빈을 등록한다. 

(@Configuration, @Controller, @Service, @Repository 등은 모두 내부에 @Component를 포함하고 있다.)

 

스프링 부트를 사용할 때는 @SpringBootApplication 을 프로젝트 시작 루트 위치에 두는 것이 일반적이다.

(@SpringBootApplication은 내부적으로 @Component를 포함한다.)

 

 

 

또한 굳이 AppConfig 내부에서 @Bean을 통해 의존성 주입을 수동으로 해주지 않아도 @Autowired를 통해 자동으로 의존성 주입을 해줄 수 있다.

@Component
public class MemberServiceImpl implements MemberService {

    private final MemberRepository memberRepository;

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

이렇게 생성자에 @Autowired를 달아 의존성 생성자 주입을 자동으로 해줄 수 있다.

(@Autowired 를 찾으면 해당 함수의 파라미터의 타입으로 주입할 빈을 찾는다.)

(필드주입에도 @Autowired 사용 가능함)

 

이때, 만약 등록할 빈의 클래스에 @Component가 붙어있지 않거나 스캔의 범위에서 벗어나있어 빈 등록이 되지 않았을 경우 에러가 발생한다.

 

또한, 해당 빈의 타입으로 여러 가지 빈이 존재할 수 있는데 이 경우에는 @Qualifier 를 통해 어떤 타입의 빈을 주입할 것인지 명시할 수 있다.

@Component
public class MemberServiceImpl implements MemberService {

    private final MemberRepository memberRepository;

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

.
.
.

@Repository("memory")
public class MemoryMemberRepository implements MemberRepository {
    ...
}

의존성 주입에서 우선순위를 두고 싶은 빈의 이름을 @Qualifier에 담아 어노테이션을 달아놓으면 해당 빈을 우선적으로 찾아 주입한다.

(codeung.tistory.com/116 에서 좀 더 자세히 설명)

 

 

 

 

출처 : www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard

+ Recent posts