
오늘은 Spring Boot 환경에서 main() 한 줄 뒤에 벌어지는 일들을 정리해보겠습니다.
아직은 Spring이 아닙니다. Spring Boot 실행 전에는 먼저 다음과 같은 일이 발생합니다.
이 한 줄에서 시작됩니다. 절차는 다음과 같습니다.
구성은 다음과 같습니다.
이 단계에선 다음 어노테이션이 동작할 준비를 합니다.
@Value
@ConfigurationProperties
@ConditionalOnProperty
WebApplicationType에 따라 다음 중 하나가 생성됩니다.
- AnnotationConfigServletWebServerApplicationContext
- AnnotationConfigReactiveWebServerApplicationContext
- AnnotationConfigApplicationContext
이 객체는 단순 DI 컨테이너가 아니라, BeanFactory ,EventPublisher, ResourceLoader를 모두 포함하는 통합 컨테이너다.
context.refresh(); 메서드 안에서는 다음과 같은 일이 발생합니다.
아직 객체는 생성되지 않고, 다음과 같은 일을 수행합니다.
- @ComponentScan 수행
- @Configuration 클래스 파싱
- @Bean 메서드 분석
- @Import 처리
- AutoConfiguration 후보 등록
이 단계에서 메모리에 저장되는 것은 BeanDefinition입니다. 실제 객체가 아닙니다.
@EnableAutoConfiguration은 내부적으로 AutoConfigurationImportSelector를 통해 자동 설정 목록을 읽습니다.
Boot 3.x를 기준으로 META- INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 파일에서 설정 후보를 로드합니다.
그리고 각 설정 클래스는 다음 조건을 검사합니다.
- @ConditionalOnClass
- @ConditionalOnMissingBean
- @ConditionalOnProperty
조건이 맞을 때만 BeanDefinition을 등록합니다.
즉, Spring Boot는 “자동 설정”이 아니라 “조건 기반 조립 시스템”이라는 것입니다.
Bean이 만들어지기 전에 BeanDefinition을 수정할 기회를 제공합니다.
대표적인 작업은 다음과 같습니다.
- placeholder 치환
- 설정 값 바인딩 준비
Bean 생성 후, 개입할 후처리기를 등록합니다. 여기서 AOP 프록시 생성기들이 준비됩니다.
이제 실제 객체가 생성됩니다.
생성 순서는 다음과 같습니다.
- 생성자 호출
- 의존성 주입
- Aware 콜백
- @PostConstruct
- InitializingBean
- BeanPostProcessor afterInitialization
여기서 CGLIB 기반 프록시가 생성될 수 있습니다.
Servlet 환경이라면, 기본은 Apache Tomcat입니다.
Spring Boot는 아래 시점에서 8080 포트를 엽니다.
- TomcatServletWebServerFactory Bean 생성
- Tomcat 인스턴스 생성
- Connector 생성
- 포트 바인딩
- DispatcherServlet 등록
- Tomcat.start() 호출
이 단계에서 다음과 같은 일을 진행합니다.
- HandlerMapping 구성
- HandlerAdapter 등록
- ExceptionResolver 설정
- ViewResolver 등록
이제 요청을 받을 준비가 완료됩니다.
이제 마지막으로 ApplicationStartedEvent, ApplicationReadyEvent가 순서대로 발행됩니다.
이 시점부터 트래픽 처리가 가능합니다.
JVM 시작
↓
SpringApplication 생성
↓
Environment 준비
↓
ApplicationContext 생성
↓
refresh()
├─ BeanDefinition 등록
├─ AutoConfiguration 조건 평가
├─ BeanFactoryPostProcessor
├─ BeanPostProcessor
└─ Singleton Bean 생성
↓
내장 WAS 기동
↓
ApplicationReadyEvent
Spring Boot는 단순 서버 기동이 아닙니다. 클래스패스 분석, 조건 평가, Bean 정의 등록, 프록시 생성, 이벤트 발생, 내장 서버 기동까지 이어지는 런타임의 조립 과정입니다.
main() 메서드 한 줄 뒤에는 수십 개의 전략과 수백 개의 Bean 정의가 조립되는 과정이 숨어 있습니다.