지금까지는 스프링 빈을 등록할 때 자바 코드의 @Bean이나 XML의 을 통해 설정 정보에 직접 등록할 스프링 빈을 나열했지만, 이 과정은 반복이 많고 누락 문제도 발생한다. 그래서 스프링은 설정 정보 없이 자동으로 빈을 등록하는 컴포넌트 스캔과 자동으로 의존관계를 주입하는 @Autowired 기능을 제공한다.
컴포넌트 스캔은 @Component 애노테이션이 붙은 클래스를 스캔해 스프링 빈으로 동록한다.
🖥️ AutoAppConfig
@Configuration
@ComponentScan(
basePackages = "hello.core.member",
basePackageClasses = AutoAppConfig.class,
excludeFilters = @Filter(type = FilterType.ANNOTATION, classes = Configuration.class)
)
public class AutoAppConfig {
}
@ComponentScan을 설정 정보에 붙이면 됨
@ComponentScan은 @Component가 붙은 모든 클래스를 스프링 빈으로 등록한다. 이때 스프링 빈의 기본 이름은 클래스 명을 사용하되 맨 앞글자만 소문자로 사용한다. 직접 지정하려면 @Component("")로 부여하면 된다.
생성자에 @Autowired를 지정하면, 스프링 컨테이너가 자동으로 해당 스프링 빈을 찾아 주입한다. (= getBean(MemberRepository))
👉 @Controller, @Service, @Repository, @Configuration는 @Component를 포함한다. 애노테이션에는 상속관계라는 것은 없어 애노테이션이 특정 애노테이션을 들고 있는 것을 인식하는 것은 자바 언어가 지원하는 기능이 아니라 스프링이 지원하는 기능이다.
🖥️ MyIncludeComponent
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyIncludeComponent {
}
🖥️ BeanA
@MyIncludeComponent
public class BeanA {
}
🖥️ ComponentFilterAppConfig
@Configuration
@ComponentScan(
includeFilters = @Filter(type = FilterType.ANNOTATION, classes = MyIncludeComponent.class),
excludeFilters = @Filter(type = FilterType.ANNOTATION, classes = MyExcludeComponent.class),
// @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = BeanA.class)
)
static class ComponentFilterAppConfig {
}
📌 FilterType
org.example.SomeAnnotationorg.example.SomeClassorg.example..*Service+org\.example\.Default.*org.example.MyTypeFilter컴포넌트 스캔에서 같은 빈 이름을 등록하면 어떻게 될까❓
ConflictingBeanDefinitionException 예외 발생