본문 바로가기
프로그래밍/Spring

[Spring] 컴포넌트 스캔

by YuminK 2023. 7. 16.

컴포넌트 스캔과 의존관계 자동 주입 

1. 스프링은 AppConfig를 만들어서 @Bean 어노테이션을 주는 방식이 아닌, 컴포넌트 스캔 방식을 제공한다.

2. 의존관계를 자동으로 주입하는 @Autowired 기능을 제공한다.

3. @Component 어노테이션을 클래스에 붙이면 Bean 객체로 할당이 된다.

 

AutoAppConfig.java

package hello.core;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import static org.springframework.context.annotation.ComponentScan.*;
@Configuration
@ComponentScan(
 excludeFilters = @Filter(type = FilterType.ANNOTATION, classes =
Configuration.class))
public class AutoAppConfig {

}

 

@ComponentScan을 설정 정보에 붙여준다.

@Bean으로 객체를 등록할 필요가 없다. 대신 각 클래스마다 @Component를 붙인다.

 

@Component

public class MemoryMemberRepository implements MemberRepository {}

 

@Component

public class RateDiscountPolicy implements DiscountPolicy {}

@Component
public class MemberServiceImpl implements MemberService {
 private final MemberRepository memberRepository;
 
 @Autowired
 public MemberServiceImpl(MemberRepository memberRepository) {
 this.memberRepository = memberRepository;
 }
 
}

 

@Component
public class OrderServiceImpl implements OrderService {
 private final MemberRepository memberRepository;
 private final DiscountPolicy discountPolicy;
 
 @Autowired
 public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy
discountPolicy) {
 this.memberRepository = memberRepository;
 this.discountPolicy = discountPolicy;
 }
 
}

OrderSerivceImpl이나 MemberServiceImpl의 생성자에 @Autowired를 붙여 자동으로 의존 관계를 주입하도록 한다. 

 

@ComponentScan 방식

@Component 어노테이션을 사용한 모든 클래스를 스프링 빈으로 등록한다.

 

@Autowired 의존관계 자동 주입 방식

생성자에 @Autowired를 지정하여 자동으로 주입한다. 

@ComponentScan(

     basePackages = {"hello.core", "hello.service"} 

)

 

basePackages: 탐색할 패키지의 시작 위치를 지정한다. 

basePackageClasses: 지정한 클래스의 패키지를 탐색 시작 위치로 지정한다.

 

권장하는 방법

패키지 위치를 지정하지 않고, 설정 정보 클래스의 위치를 프로젝트 최상단에 두는 것이다. (스프링 관례)

 

컴포넌트 스캔 기본 대상

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

@Component : 컴포넌트 스캔에서 사용

@Controller : 스프링 MVC 컨트롤러에서 사용

@Service : 스프링 비즈니스 로직에서 사용

@Repository : 스프링 데이터 접근 계층에서 사용

@Configuration : 스프링 설정 정보에서 사용

 

스프링 어노테이션 부가 기능

@Controller : 스프링 MVC 컨트롤러로 인식

@Repository : 스프링 데이터 접근 계층으로 인식하고, 데이터 계층의 예외를 스프링 예외로 변환해준다.

@Configuration : 앞서 보았듯이 스프링 설정 정보로 인식하고, 스프링 빈이 싱글톤을 유지하도록 추가 처리를 한다. @Service : 사실 @Service 는 특별한 처리를 하지 않는다. 대신 개발자들이 핵심 비즈니스 로직이 여기에 있겠구나 라고 비즈니스 계층을 인식하는데 도움이 된다.

 

필터

includeFilters : 컴포넌트 스캔 대상을 추가로 지정한다.

excludeFilters : 컴포넌트 스캔에서 제외할 대상을 지정한다

 

중복 등록과 충돌

수동 빈 등록과 자동 빈 등록에서 이름이 충돌나는 경우에는 어떻게 처리될까?

=> 수동 빈이 자동 빈을 오버라이딩한다.

그러나 최근에는 이름이 같은 애매한 상황을 스프링에서 막아 에러를 출력한다. 

댓글