@SpringBootApplication
public class BamduleApplication {
public static void main(String[] args) {
SpringApplication.run(BamduleApplication.class, args);
}
}
스프링부트는 main 메소드가 선언된 클래스를 기준으로 실행된다.
@SpringBootApplication 어노테이션은 스프링부트의 가장 기본적인 설정을 선언해준다.
해당 어노테이션을 상세히 보면, 아래와 같은 어노테이션들이 다시 선언되어 있다.
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
@AliasFor(
annotation = EnableAutoConfiguration.class
)
Class<?>[] exclude() default {};
@AliasFor(
annotation = EnableAutoConfiguration.class
)
String[] excludeName() default {};
@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackages"
)
String[] scanBasePackages() default {};
@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackageClasses"
)
Class<?>[] scanBasePackageClasses() default {};
@AliasFor(
annotation = ComponentScan.class,
attribute = "nameGenerator"
)
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
@AliasFor(
annotation = Configuration.class
)
boolean proxyBeanMethods() default true;
}
이 중에서 눈여겨볼 설정은 @ComponentScan과 @EnabledAutoConfiguration이다.
스프링부트는 Bean을 두번 등록한다.
먼저 @ComponentScan으로 등록한다음, @EnabledAutoConfiguration으로 수집된 Bean을 등록한다. 그래서 사실상, @EnabledAutoConfiguration없이 @ComponentScan만 있어도 기동이 가능하다.
@ComponentScan은 @Component 어노테이션 및 @Service, @Repository, @Controller 등의 어노테이션을 스캔하여 Bean으로 등록해주는 어노테이션이다.
해당 패키지에 속해있는 클래스에 대해서만 스캔을 하기 때문에, 메인 패키지 바로 아래에 등록해주어야 사용되는 클래스들을 스캔할 수 있다.
@EnabledAutoConfiguration은 사전에 정의한 라이브러리들(meta파일에서 읽어냄)을 Bean으로 등록해주는 어노테이션이다. 사전에 정의한 라이브러리들 모두가 등록되지는 않고, 특정 조건이 만족될 경우에 Bean으로 등록한다.
@OnBeanCondition : 특정 Bean이 사전에 생성되어있지 않을 경우에 조건이 만족됨
@ConditionalOnBean : 특정 Bean이 이미 생성되어있을 경우에 조건이 만족됨
@ConditionalOnClass : Classpath에 특정 class가 존재할 경우에 조건이 만족됨