김영한씨의 스프링 핵심 원리 - 기본편 강의를 듣고 공부 겸 정리하는 글입니다.
지금까지는 @Bean 어노테이션을 통해 스프링 빈에 등록할 모든 것들을 지정했습니다. 갯수가 늘어나면 반복해서 작성해야할 코드가 적지 않은데요,,
이를 해결하기 위해 설정정보가 없어도 자동으로 스프링 빈을 등록하는 컴포넌트 스캔을 제공합니다.
또한 의존관계도 바로 주입하는 Autowired가 존재합니다.
@Configuration
@ComponentScan(
excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classses = 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;
}
}
빈 이름 | 빈 객체 |
---|---|
memberServiceImpl | MemberServiceImpl@x01 |
orderServiceImpl | OrderServiceImpl@x02 |
memoryMemberRepository | MemoryMemberRepositoryImpl@x03 |
rateDiscountPolicy | RateDiscountPolicyImpl@x04 |
모든 클래스를 다 컴포넌트 스캔하면 시간이 오래 걸리기 때문에 탐색 위치를 지정할 수 있습니다.
@ComponentScan(
basePackages = "hello.core"
)
지정하지 않으면 @ComponentScan이 붙은 설정 정보 클래스의 패키지가 시작 위치가 됩니다.
주로 권장하는 방법은 설정 정보 클래스를 프로젝트 상단에 두어 basePackages를 생략하는 방법입니다. 이렇게 하면 프로젝트 하부 패키지는 모두 스캔하기 때문이지요..
@Component @Controller @Service @Repository @Configuration
해당 클래스들은 @Component를 포함하고 있습니다.
두 가지의 상황이 존재합니다.
컴포넌트 스캔에 의해 자동으로 등록 될 때, 이름이 같게 되면 무슨 일이 일어날까요?
정답은 ConflictingBeanDefinitionException
예외가 발생한다 입니다.
이름이 같아 충돌하게 된다면 수동 빈 등록이 우선권을 가집니다. 즉, 수동 빈이 자동 빈을 오버라이딩 한다는 이야기,,
하지만, 최근에는 스프링 측에서 그냥 오류로 만들어 버린답니다.