티스토리 뷰
stereotype annotation들을 어떻게 찾을까?
스프링 부트가 시작되는 클래스에 붙어있는 SpringBootApplication 어노테이션을 조사해보았습니다.
여러 어노테이션이 있으나 @EnableAutoConfiguration와 @ComponentScan을 살펴보겠습니다.
1. EnableAutoConfiguration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
/**
* Environment property that can be used to override when auto-configuration is
* enabled.
*/
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
/**
* Exclude specific auto-configuration classes such that they will never be applied.
* @return the classes to exclude
*/
Class<?>[] exclude() default {};
/**
* Exclude specific auto-configuration class names such that they will never be
* applied.
* @return the class names to exclude
* @since 1.3.0
*/
String[] excludeName() default {};
}
스프링 애플리케이션 컨텍스트의 auto-configuration을 사용하도록 설정하여 필요할 것 같은 bean을 추측하고 구성합니다.
auto-configuration 클래스는 일반적으로 classpath와 정의한 bean을 기준으로 적용됩니다.
예를 들어, classpath에 tomcat-embedded.jar가 있는 경우, TomcatServletWebServerFactory을 원할 수 있습니다. (자신의 ServletWebServerFactory bean을 정의하지 않았음에도)
@SpringBootApplication을 사용할 때 컨텍스트의 auto-configuration이 자동으로 활성화되므로 이 주석을 추가해도 아무런 효과가 없습니다.
auto-configuration은 가능한 한 지능적이게 노력하며 사용자 자신의 configuration을 더 많이 정의할수록 후순위로 밀려납니다.
적용하지 않을 구성은 exclude()로 제외할 수 있습니다.
또한 spring.autoconfigure.exclude property를 통해 제외할 수 있습니다.
auto-configuration는 항상 사용자 정의 bean을 등록한 후에 적용됩니다.
일반적으로 @SpringBootApplication을 통해 @EnableAutoConfiguration이 선언된 클래스의 패키지는 특정 의미를 가지며 종종 '기본값'으로 사용됩니다.
예를 들어 @Entity 클래스를 검색할 때 사용됩니다.
일반적으로 모든 하위 패키지 및 클래스를 검색할 수 있도록 루트 패키지에 @EnableAutoConfiguration(@SpringBootApplication을 사용하지 않는 경우)를 배치하는 것이 좋습니다.
auto-configuration 클래스는 일반적으로 Spring의 @Configuration bean입니다.
ImportCandidates 및 SpringFactoriesLoader 메커니즘을 사용하여 위치를 파악합니다.
SpringFactoriesLoader는 META-INF/spring.factories 파일을 사용합니다.
일반적으로 auto-configuration 빈은 @Conditional이 붙은 Bean입니다.
(대부분 @ConditionalOnClass 및 @ConditionalOnMissingBean 주석을 사용합니다).
2. ComponentScan
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;
boolean useDefaultFilters() default true;
Filter[] includeFilters() default {};
Filter[] excludeFilters() default {};
boolean lazyInit() default false;
@Retention(RetentionPolicy.RUNTIME)
@Target({})
@interface Filter {
FilterType type() default FilterType.ANNOTATION;
@AliasFor("classes")
Class<?>[] value() default {};
@AliasFor("value")
Class<?>[] classes() default {};
String[] pattern() default {};
}
}
@Configuration을 사용하는 클래스에서 사용할 component scanning 지시문을 구성합니다.
Spring XML의 <context:component-scan> 요소를 병렬로 지원합니다.
검색할 특정 패키지를 정의하기 위해 basePackageClasses() 또는 basePackages() 또는 해당 별칭 값()을 지정할 수 있습니다.
특정 패키지가 정의되지 않은 경우 ComponentScan 어노테이션을 선언하는 클래스의 패키지에서 검색이 수행됩니다.
<context:component-scan> 요소에는 annotation-config 속성이 있지만, ComponentScan 주석에는 없습니다.
이는 @ComponentScan을 사용할 때 거의 모든 경우에 기본 주석 구성 처리(예: @Autowired)가 가정되기 때문입니다.
또한 AnnotationConfigApplicationContext를 사용할 때 annotation config 프로세서는 항상 등록되므로 @ComponentScan 수준에서 사용하지 않도록 설정하려는 시도는 무시됩니다.
@Configuration을 사용하는 클래스를 스캔한다고 하니 @Configuration도 살펴보겠습니다.
3. Configuration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
@AliasFor(annotation = Component.class)
String value() default "";
boolean proxyBeanMethods() default true;
}
클래스가 하나 이상의 @Bean 메서드를 선언하고 런타임에 해당 bean에 대한 bean 정의 및 서비스 요청을 생성하기 위해 스프링 컨테이너에 의해 처리될 수 있음을 나타냅니다.
@Configuration
public class AppConfig {
@Bean
public MyBean myBean() {
// instantiate, configure and return bean ...
}
}
@Configuration 클래스는 일반적으로 AnnotationConfigApplicationContext 혹은 AnnotationConfigWebApplicationContext를 사용하여 부트스트랩됩니다.
AnnotationConfigApplicationContext의 간단한 예는 다음과 같습니다.
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(AppConfig.class);
ctx.refresh();
MyBean myBean = ctx.getBean(MyBean.class);
// use myBean ...
AnnotationConfigApplicationContext에 직접 @Configuration 클래스를 등록하는 대신 @Configuration 클래스를 Spring XML 파일 내에서 일반 <bean> 정의로 선언할 수 있습니다.
<beans>
<context:annotation-config/>
<bean class="com.acme.AppConfig"/>
</beans>
위의 예에서 ConfigurationClassPostProcessor 및 @Configuration 클래스를 쉽게 처리할 수 있는 다른 주석 관련 포스트 프로세서를 활성화하려면 <context:annotation-config/>가 필요합니다.
@Configuration은 @Component에 meta-annotated되므로 @Configuration 클래스는 component scanning의 후보입니다.
따라서 일반 @Component처럼 @Autowired/@Inject를 활용할 수도 있습니다.
특히, 단일 생성자가 존재하는 경우 자동으로 해당 생성자에 대해 적용될 것입니다.
@Configuration
public class AppConfig {
private final SomeBean someBean;
public AppConfig(SomeBean someBean) {
this.someBean = someBean;
}
// @Bean definition using "SomeBean"
}
@Configuration 클래스는 component scanning을 사용하여 부트스트랩할 수 있을 뿐만 아니라 @ComponentScan 주석을 사용하여 구성 요소 검색을 구성할 수도 있습니다.
@Configuration
@ComponentScan("com.acme.app.services")
public class AppConfig {
// various @Bean definitions ...
}
결론
@SpringBootApplication에 있는 @ComponentScan에서 @Configuration을 사용하는 클래스에서 사용할 component scanning 지시문을 구성합니다.
@Configuration은 @Component에 meta-annotated되므로 @Component 클래스 또한 component scanning의 후보입니다.
전 포스팅에서 살펴봤듯이 Indexed 제외한 stereotype 어노테이션이 붙은 어노테이션들은 @Component가 붙어있습니다.
stereotype annotation?
stereotype annotation이 무엇일까? 전체 아키텍처에서 type 혹은 method의 역할을 나타내는 어노테이션을 뜻합니다. 종류로는 Component, Controller, Indexed, Repository, Service가 있습니다. 1. Indexed @Tar..
kkoon9.tistory.com
따라서, stereotype 어노테이션이 bean으로 등록될 수 있었던 겁니다.
'Sping Framework' 카테고리의 다른 글
스프링의 IoC (0) | 2022.07.10 |
---|---|
자바빈(JavaBean) (0) | 2022.07.10 |
stereotype annotation? (0) | 2022.06.21 |
Spring MVC lifecycle (0) | 2022.05.15 |
XML In Java [2]. XML String to VO (0) | 2022.04.23 |
- Total
- Today
- Yesterday
- 이팩티브 자바
- 객체지향
- 프로그래머스
- Spring Boot
- 백준
- 정규표현식
- Olympiad
- Java
- 이펙티브 자바
- node.js
- Kotlin
- Spring
- C++
- BOJ
- 코테
- 디자인패턴
- 디자인 패턴
- 알고리즘
- BAEKJOON
- 테라폼
- 클린 코드
- Algorithm
- JPA
- Effective Java
- kotest
- AWS
- 클린 아키텍처
- programmers
- MSA
- kkoon9
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |