Notice
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
01-24 15:09
Today
Total
관리 메뉴

그날그날 공부기록

@ComponentScan & @Autowired에 대하여 본문

Spring 공부

@ComponentScan & @Autowired에 대하여

given_dragon 2022. 7. 22. 14:11
@Configuration
public class AppConfig {

    @Bean
    public MemberService memberService(){
        return new MemberServiceImpl(memberRepository());
    }
    @Bean
    public OrderService orderService(){
        return new OrderServiceImpl(memberRepository(), discountPolicy());
    }
    @Bean
    public MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }
    @Bean
    public DiscountPolicy discountPolicy(){
        return new FixDiscountPolicy();
    }
}

위의 코드처럼 수동으로 스프링 빈을 등록할 수 있지만 빈의 개수가 많아지면 여러모로 불편한 점이 많아진다.

하지만 스프링은 스캔해서 스프링 빈을 등록하는 컴포넌트 스캔이라는 기능을 제공한다.

 

@Configuration
@ComponentScan
public class AutoAppConfig {
}

새로운 설정 파일을 생성하였고, 다음과 같이 @ComponentScan을 써주면 컴포넌트 스캔이 사용된다.

컴포넌트 스캔은 @Component가 있는 클래스를 스캔해서 스프링 빈으로 등록한다.

 

따라서 기존 설정파일이었던 AppConfig에서 스프링 빈으로 등록해야 하는 클래스에 @Component를 작성해야한다.
(여기서는 MemverServiceImpl, OrderServiceImpl, MemoryMemberRepository, FixDiscountPolicy)

@Component
public class MemberServiceImpl implements MemberService{

    private final MemberRepository memberRepository;

    ...
    ...
}

 

그리고 AppConfig에서 직접 명시하였던 의존관계 정보가 없기 때문에 클래스의 생성자에 @Autowired를 작성해주어야 한다.

이렇게 작성하면 의존관계가 자동으로 주입된다.

@Component
public class MemberServiceImpl implements MemberService{

    private final MemberRepository memberRepository;

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

    ...
    ...
}

 

ComponentScan과 Autowired는 어떤 방식으로 동작될까?

  • @ComponentScan
    • @Component가 붙은 모든 클래스를 스캔 & 스프링 빈으로 등록
    • 해당 빈의 이름은 클래스 명을 사용하고 맨 앞글자를 소문자로 사용(MemberServiceImpl → memberServiceImpl)
    • 빈의 이름을 직접 지정하려면 다음과 같이 사용. @Component(”빈 이름")
  • @Autowired
    • 생성자에 @Autowired가 있다면 스프링 컨테이너가 자동으로 빈을 주입한다.
    • 같은 타입의 빈을 찾아서 주입 (같은 타입이 여러개거나 없으면 오류가 난다.)

ComponentScan의 탐색 위치기본 스캔 대상

@Configuration
@ComponentScan(
        basePackages = "hello.core.member"
)
public class AutoAppConfig {

}

컴포넌트 스캔의 스캔 위치를 별도로 지정할 수 있다. 지정하지 않으면 @ComponentScan이 있는 클래스의 패키지를 기본 위치로 설정한다.

  • 위와같이 basePackages에 원하는 시작 위치를 입력하면 해당 위치부터 하위 패키지를 스캔한다.
    • basePackages={”hello.core.order”, “hello.core.member”}처럼 여러 위치를 지정할 수 있다.
  • basePackageClasses
    • 지정한 클래스의 패키지를 스캔한다.

하지만 이렇게 일일히 별도로 지정하기 보다는 프로젝트 파일의 최상단에 두는것을 권장하신다고 한다.
위 사진의 프로젝트 구조에서는 hello.core가 되겠다.

스프링 부트를 사용하면 @SpringBootApplication을 프로젝트 파일의 최상단에 위치시키는 것이 관례인데 @Component을 포함하고 있기 때문이다.


ComponentScan의 기본 스캔 대상

컴포넌트 스캔은 @Component를 포함해서 여러가지를 스캔한다.

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

왜냐하면 해당 애노테이션들이 @Component를 포함하고 있기 때문이다.

@Service
@Repository
@Configuration

'Spring 공부' 카테고리의 다른 글

스프링의 의존관계 주입 방법 2  (0) 2022.07.27
스프링의 의존관계 주입 방법  (0) 2022.07.26
스프링의 @Configuration과 싱글톤  (0) 2022.07.21
싱글톤 방식의 주의점  (0) 2022.07.21
싱글톤 컨테이너  (0) 2022.07.19
Comments