Spring Boot Auto-Configuration

2024. 10. 18. 17:27Spring Boot/Spring Boot Auto Configuration

Spring Boot의 자동 구성(auto-configuration)은 매우 세밀하게 설계된 프로세스로, 애플리케이션이 시작될 때 필요한 다양한 설정을 자동으로 처리합니다. 이 과정을 단계별로 상세하게 설명하겠습니다. 각 클래스와 메커니즘이 어떻게 상호작용하는지를 살펴보며, 최종적으로 자동 구성이 어떻게 이루어지는지 깊이 이해할 수 있도록 하겠습니다.


1. 애플리케이션 시작: @SpringBootApplication, @EnableAutoConfiguration, @AutoConfigurationPackage

Spring Boot 애플리케이션이 시작될 때, 개발자는 일반적으로 @SpringBootApplication 애노테이션을 사용합니다. 이 애노테이션은 내부적으로 세 가지 중요한 애노테이션을 포함하고 있습니다:

  • @SpringBootConfiguration: 일반적인 Spring의 @Configuration을 확장한 것으로, 애플리케이션 설정을 정의하는 데 사용됩니다.
  • @EnableAutoConfiguration: 이 애노테이션이 핵심입니다. Spring Boot의 자동 구성을 트리거하고, 자동으로 필요한 빈과 설정을 찾습니다.
  • @ComponentScan: 애플리케이션의 패키지 구조에서 컴포넌트 탐색을 활성화하여, @Component, @Service, @Repository, @Controller와 같은 클래스들을 스캔하고 빈으로 등록합니다.

또한, @AutoConfigurationPackage는 자동 구성이 애플리케이션의 패키지 범위 내에서 패키지 스캔이 이루어지도록 돕습니다. 이 패키지 내에서 모든 구성 요소들이 감지되고, 필요한 빈들이 자동으로 등록됩니다.


2. 자동 구성 클래스를 찾아라: AutoConfigurationImportSelector

@EnableAutoConfiguration이 활성화되면, Spring Boot는 AutoConfigurationImportSelector를 호출합니다. 이 클래스는 자동 구성을 위한 핵심적인 역할을 하며, 클래스패스에 있는 다양한 자동 구성 클래스들을 찾아내는 역할을 합니다.

  1. 클래스 로드: AutoConfigurationImportSelector는 클래스패스에서 자동 구성 클래스들을 찾아냅니다. 이 과정에서 spring.factories 파일과 AutoConfiguration.imports 파일을 이용합니다.
    • spring.factoriesMETA-INF 디렉토리에 위치한 파일로, Spring Boot가 자동 구성을 위해 사용할 여러 구성 클래스들의 목록을 제공합니다.
    • AutoConfiguration.importsSpring Boot 3.0 이상에서 추가된 최적화 방식으로, 자동 구성 클래스를 좀 더 효율적으로 관리하기 위해 등장했습니다.
    • 이 목록은 spring-boot-autoconfigure.jar에 포함된 클래스들로 구성되어 있습니다.
  2. 필터링: 자동 구성 클래스들이 무조건 로드되는 것이 아닙니다. Spring Boot는 컨디셔널(조건부) 로직을 적용하여, 특정 조건이 만족되지 않으면 자동 구성 클래스를 로드하지 않거나, 특정 빈을 생성하지 않습니다. 예를 들어, @ConditionalOnClass는 특정 클래스가 클래스패스에 존재할 때만 설정을 활성화하는 방식입니다.

3. 자동 구성 클래스 로드: spring.factoriesAutoConfiguration.imports

자동 구성에 필요한 클래스들은 AutoConfigurationImportSelector에 의해 선택되고, 실제로 로드됩니다. 이때 사용되는 파일들이 바로 spring.factoriesAutoConfiguration.imports입니다.

  • spring.factories 파일에는 EnableAutoConfiguration 키를 기준으로 여러 자동 구성 클래스들이 나열되어 있습니다. 예를 들어, DataSourceAutoConfiguration, WebMvcAutoConfiguration 같은 클래스들이 포함됩니다. Spring Boot는 이 파일을 읽어 필요한 구성들을 자동으로 로드합니다.
  • AutoConfiguration.imports는 보다 간결한 방식으로 자동 구성 클래스들을 관리하며, Spring Boot 3.0에서 성능 최적화를 위해 도입된 방식입니다.

이 과정에서는 자동 구성에 필요한 모든 후보 클래스들이 선택되고, 애플리케이션에서 실제로 사용할 수 있는 상태로 준비됩니다.


4. 지연된 구성 처리: DeferredImportSelector

일부 자동 구성 클래스는 즉시 처리되지 않고, 지연 처리될 필요가 있습니다. 이 경우 DeferredImportSelector가 사용됩니다.

  • DeferredImportSelector는 Spring 컨텍스트의 초기화가 완료된 이후에 필요한 추가적인 구성 클래스를 처리합니다. 보통 나중에 처리되어야 하는 설정이 있을 때 이 메커니즘이 동작합니다.
  • 이 지연된 구성은 특정 순서를 보장하거나, 컨텍스트가 완전히 준비된 후에 필요한 설정을 적용할 때 유용합니다. 예를 들어, Spring Security나 데이터베이스 연결과 같은 일부 구성이 지연되어 처리될 수 있습니다.

5. 웹 애플리케이션 설정: AnnotationConfigServletWebServerApplicationContext

Spring Boot 애플리케이션이 웹 기반일 경우, 내장 웹 서버가 함께 실행됩니다. 이 과정에서 사용되는 것이 바로 AnnotationConfigServletWebServerApplicationContext입니다.

  1. 내장 웹 서버 설정: Spring Boot는 자동으로 Tomcat, Jetty, Undertow와 같은 내장 웹 서버를 설정합니다. 이는 애플리케이션의 application.properties 또는 application.yml에 따라 포트 번호나 SSL 설정 등을 자동으로 구성합니다.
  2. 서블릿 컨텍스트 생성: AnnotationConfigServletWebServerApplicationContext는 서블릿 기반의 웹 애플리케이션에서 사용되는 핵심 컴포넌트들을 설정합니다. 이를 통해 DispatcherServlet, 필터, 리스너가 자동으로 등록되고, 웹 요청을 처리할 준비를 갖추게 됩니다.

6. 구성 클래스 파싱: ConfigurationClassParser

자동 구성 클래스가 모두 로드되면, Spring의 ConfigurationClassParser가 이를 파싱하기 시작합니다. 이 파서의 역할은 구성 클래스들에서 실제로 사용할 빈 정의를 추출하고, 이를 애플리케이션 컨텍스트에 등록하는 것입니다.

  • 빈 정의 추출: @Bean, @Component, @Service 등으로 선언된 빈들을 추출하여 빈 팩토리에 등록합니다.
  • 조건부 구성: @Conditional 애노테이션을 사용하여 특정 조건이 만족될 때만 구성되는 설정들이 포함됩니다. 예를 들어, DataSourceAutoConfiguration데이터소스 관련 빈이 이미 존재하지 않을 때만 자동으로 설정됩니다.

이 과정은 매우 중요한데, 자동 구성된 클래스들이 어떻게 실제로 구성 요소로 변환되는지 결정하는 핵심적인 단계입니다.


7. 빈 등록: DefaultListableBeanFactory

Spring Boot는 자동 구성을 통해 파싱된 구성 클래스들[spring-boot-autoconfigure.jar 에 있는]에서 추출한 빈 정의를 Spring의 DefaultListableBeanFactory에 등록합니다.

  • 빈 관리: DefaultListableBeanFactory는 Spring 애플리케이션에서 사용되는 모든 빈들의 생명 주기를 관리합니다. 여기에는 빈의 생성, 의존성 주입, 소멸 등의 작업이 포함됩니다.
  • 자동 구성 빈: 자동 구성에 의해 등록된 빈들도 여기에 포함됩니다. 예를 들어, DataSource, EntityManagerFactory, MessageConverter 등이 자동으로 등록됩니다.

빈 팩토리는 애플리케이션 실행 중 필요한 시점에 빈을 생성하고, 의존성을 주입하여 애플리케이션이 원활히 동작할 수 있도록 지원합니다.


8. 후처리 작업: PostProcessorRegistrationDelegate, ConfigurationClassPostProcessor

빈이 모두 등록된 후에는 후처리 단계가 이어집니다. 이 단계에서 Spring Boot는 빈의 생명 주기를 더욱 최적화하고, 추가적인 작업을 처리합니다.

  • PostProcessorRegistrationDelegate는 여러 후처리기(BeanFactoryPostProcessor, BeanPostProcessor)를 등록하여 빈이 등록된 후의 작업을 처리합니다. 이를 통해 빈이 완전히 준비된 상태에서 추가적인 설정이나 후처리가 가능합니다.
  • ConfigurationClassPostProcessor@Configuration 클래스들을 처리하고, 빈 정의를 최종적으로 애플리케이션 컨텍스트에 등록하는 역할을 합니다.

이 후처리 단계는 빈이 최적의 상태로 애플리케이션 내에서 동작할 수 있도록 하는 마지막 과정입니다.


9. 애플리케이션 실행

모든 자동 구성 과정이 완료되면, Spring Boot는 애플리케이션을 실제로 실행합니다. 웹 애플리케이션의 경우, 내장 웹 서버가 요청을 처리할 준비를 마치고, 클라이언트 요청에 응답할 수 있는 상태가 됩니다. 데이터베이스 연결, 보안 설정 등도 자동으로 완료됩니다.

이 단계까지 모든 자동 구성이 완료되어, 개발자는 설정 작업 없이도 다양한 기능을 사용할 수 있습니다.