- 기존) 스프링 빈 등록시, @Bean 이나 XML의 bean 태그 등을 통해서 설정 정보에
직접 등록할 스프링 빈을 나열
단점)등록해야 할 빈이 수천개가 될 수도...
해결) '설정 정보' 없이 자동으로 스프링 빈을 등록하자 => "컴포넌트 스캔"
그리고 의존관계 자동 주입을 위한 @Autowired
+) @Configuration은 사실 코드 이내에 @Component 애노테이션이 붙음.
-> 그래서 컴포넌트 스캔 대상이 됨 처음에,,,
@Configuration
@ComponentScan(
excludeFilters = @Filter(type = FilterType.ANNOTATION, classes =
Configuration.class))
//Connfiguration.class는 컴포넌트 스캔 대상에서 예외 시킴.
public class AutoAppConfig {
}
- 설정 정보에 @ComponentScan 붙여서 컴포넌트 스캔 사용을 설정.
- @Component 가 붙은 클래스들을 스캔하여 '스프링 빈'으로 등록
@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;
}
}
@Autowired 사용하여 생성자에서 여러 의존관계를 한 번에 주입 받는다.
@Component : 컴포넌트 스캔에서 사용
@Controlller : 스프링 MVC 컨트롤러에서 사용
@Service : 스프링 비즈니스 로직에서 사용
@Repository : 스프링 데이터 접근 계층에서 사용, 컴포넌트 스캔은 @Component 뿐만 아니라 다음과 내용도 추가로 대상에 포함한다.
+)@Configuration : 앞서 보았듯이 스프링 설정 정보로 인식하고, 스프링 빈이 싱글톤을 유지하도록 추가
처리를 한다
//컴포넌트 스캔 대상에 '추가할 애노테이션' => @MyIncludeComponent
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyIncludeComponent {
}
--
//컴포넌트 스캔 대상에 '제외할 애노테이션' => @MyExcludeComponent
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyExcludeComponent {
}
--
//컴포넌트 스캔 대상에 추가할 클래스
@MyIncludeComponent //지정한 어노테이션 설정
public class BeanA { }
--
//컴포넌트 스캔 대상에 제외할 클래스
@MyExcludeComponent //지정한 어노테이션 설정
public class BeanB { }
- includeFilters 에 MyIncludeComponent 애노테이션을 추가해서 BeanA가 스프링 빈에 등록된다.
- excludeFilters 에 MyExcludeComponent 애노테이션을 추가해서 BeanB는 스프링 빈에 등록되지
않는다.
: 만약 컴포넌트 스캔에서 같은 '빈' 이름이 등록된다면..?
그러나 요즘에는 이런 실수를 많이 저질러서인지...
최근 스프링 부트에서는'수동 빈 등록'과 '자동 빈 등록'이 충돌나면 오류가 발생하도록기본 값을 바꿈.
Consider renaming one of the beans or enabling overriding by setting
spring.main.allow-bean-definition-overriding=true
spring.main.allow-bean-definition-overriding=true 을 application.properties에 등록하면 된다.