본문 바로가기

JAVA/Spring

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

728x90

컴포넌트 스캔이란?

  • 기존에 빈을 등록할 때는 자바 설정파일이나 XML을 이용해 일일이 등록해주어야 했다.
  • 실무에서는 이렇게 등록해주어야 할 빈이 수십, 수백개가 되므로 누락하거나 반복해야하는 문제점이 발생한다.
  • 그렇기에 스프링은 설정정보가 없어도 자동으로 스프링 빈을 등록해주는 컴포넌트 스캔 이라는 기능을 제공한다.
@Configuration
@ComponentScan(
        excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Configuration.class)
)
public class AutoAppConfig {

}

컴포넌트 스캔을 사용하려면 설정정보에 @ComponentScan 어노테이션을 달아준다.

기존 설정파일과 다르게 Bean으로 등록된 클래스가 하나도 없다.

중간의 excludeFilters는 스캔 대상에서 제외하는 명령어이다.

@Configuration이 붙어있는 설정정보도 자동으로 등록되기 때문에 앞서 만든 예제에서 만든 설정정보가 중복실행 되므로 excludeFilters로 설정정보는 컴포넌트 스캔 대상에서 제외했다.

ComponentScan은 @Component 어노테이션이 붙은 클래스를 스캔해서 스프링 빈으로 등록한다. @Component를 붙여주면 된다. (Configuration 어노테이션 소스코드에도 @Component가 붙어있음)

@Component
public class MemberServiceImpl implements MemberService{

    private final MemberRepository memberRepository;

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

    @Override
    public void join(Member member) {
        memberRepository.save(member);
    }

    @Override
    public Member findMember(Long memberId) {
        return memberRepository.findById(memberId);
    }
}

@Component로 클래스를 빈 등록할 수 있지만 그 안의 의존관계는 자동으로 이루어지지 않는다.

여기서 의존관계가 필요한 부분에 @Autowired를 사용해준다.

그러면 스프링이 스프링 컨테이너 안에서 Autowired 어노테이션이 붙은 요소의 타입에 맞는 구현체를 주입해준다.

이 때 빈 이름은 CamelCase로 등록된다.

(빈 이름 : memberServiceImpl / 빈 객체 : MemberServiceImpl)

빈 이름을 직접 지정하고 싶으면 @Component("이름") 으로 직접 부여할 수 있다.

탐색 위치와 기본 스캔 대상

@ComponentScan(
        basePackages = "hello.core.member",
)

basePackages 옵션을 통해 탐색위치를 지정할 수 있다.

위와 같이 설정하면 hello.core.member 패키지만 ComponentScan 대상이 된다.

  • basePackages = {"hello.core", "hello.service"} 이렇게 여러 위치를 지정할 수 있다.
  • 지정하지 않으면 @ComponentScan이 붙은 정보 클래스의 패키지가 시작 위치가 된다.
  • basePackageClasses = AutoAppConfig.class 이와 같이 클래스로 지정할 수 있음

권장하는 사용법 : 패키지 위치를 지정하지 않고 설정 정보 클래스 위치를 프로젝트 최상단에 두는 것, 예를들어 아래와 같은 프로젝트 구조가 있다.

  • com.hello
  • com.hello.service
  • com.hello.repository

com.hello → 여기에 설정파일을 두고 ComponentScan 어노테이션을 붙여서 basePackages는 생략한다.

(스프링 부트의 경우 @SpringBootApplication이 부트의 설정 선언 어노테이션인데, 이를 프로젝트 시작 루트 위치에 두는 것이 관례이다, 이 어노테이션 안에도 @ComponentScan이 들어있음)

컴포넌트 스캔 기본 대상

컴포넌트 스캔은 @Component 뿐만 아니라 다음과 같은 내용도 대상에 포함하며 부가기능을 지니고 있다.

  • @Component : 컴포넌트 스캔에 사용
  • @Controller : 스프링 MVC 컨트롤러에서 사용 (스프링 MVC 컨트롤러로 인식)
  • @Service : 스프링 비즈니스 로직에 사용 (특별한 기능은 없으나 서비스 로직임을 인식할 수 있음)
  • @Repository : 스프링 데이터 접근 계층에서 사용 (데이터 접근 계층으로 인식, 데이터 계층의 예외를 스프링 예외로 변환해줌)
  • @Configuration : 스프링 설정 정보에서 사용 (스프링 설정 정보로 인식, 싱글톤 유지하도록 추가 처리)

'JAVA > Spring' 카테고리의 다른 글

[Spring] 빈 스코프(singleton bean, prototype bean)  (0) 2021.07.16
[Spring] 빈 생명주기의 콜백  (0) 2021.07.15
[Spring] 스프링과 싱글톤  (0) 2021.07.13
[Spring] 스프링 빈 조회하기  (0) 2021.07.09
스프링의 역사  (0) 2021.06.28