스프링 공부를 하다 기초가 너무 안되어있다는 느낌을 받았다.
과연 지금하는 프로젝트에서 내가 선언한 어노테이션과 코드들을 전부 이해하고 사용하는 것일까? 라는 질문에 처음부터 하나하나 뜯어보기로 했다.
그 처음은 스프링 프로젝트를 만들면 바로 볼 수 있는 @SpringBootApplication 어노테이션이다.
스프링 부트는 main메소드가 선언된 클래스를 기준으로 실행된다고 한다.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class PracticeApplication {
public static void main(String[] args) {
SpringApplication.run(PracticeApplication.class, args);
}
}
@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
, @SpringBootConfiguration
, @EnableAutoConfiguration
이 3가지이다.
어노테이션 클래스에 @Component를 포함한다면 Component Scan의 대상으로 인식한다.
@component, @Configuration , @Controller, @Service, @Repository 어노테이션이 선언된 하위 패키지에서 Bean을 등록한다.
등록된 빈은 @Autowired로 부를 수 있다.
실제 각 어노테이션이 @Component를 포함하는지 확인해보자
중요한 설정으로는 BasePackages 와 BasePackageClasses가 있다. 이는 스캔 위치를 설정하는 방법들인데, BasePackages는 String으로 입력된 패키지의 경로를 스캔하는 방법이고BasePackageClasses는 전달된 클래스의 위치를 기준으로 스캔을 시작하는 방법이다.
@ComponentScan은 BeanFactoryPostProcessor를 구현한 ConfigurationClassPostProcessor
에 의해 동작한다.
BeanFactoryPostProcessor는 다른 모든 Bean들을 만들기 이전에 BeanFactoryPostProcessor의 구현체들을 모두 적용한다.
즉, 다른 Bean들을 등록하기 전에 컴포넌트 스캔을해서 Bean으로 등록해준다.
스프링 부트의 설정을 나타내는 어노테이션이다. 스프링의 @Configuration을 대체하며 스프링 부트 전용 어노테이션이다. 테스트 어노테이션을 사용할 때 계속 이 어노테이션을 찾기 때문에 스프링 부트에서는 필수 어노테이션이다.
자동 설정의 핵심 어노테이션이다. 클래스 경로에 지정된 내용을 기반으로 설정 자동화를 수행한다.
스프링 부트 어플리케이션은 Bean을 2번 등록한다. 처음에 ComponentScan으로 등록하고, 그 후에 EnableAutoConfiguration으로 추가적인 Bean들을 읽어서 등록한다.
Spring Bean Container는 뭐고 Loc컨테이너는 뭘까?
[Spring Boot] @SpringBootApplication 이란?
[스프링 핵심기술] - @Component와 @ComponentScan