Spring Boot Auto-Configuration 동작 원리 완전 정복
Spring Boot Auto-Configuration이 어떻게 수백 개의 빈을 자동으로 등록하는지 내부 동작 원리를 완전히 이해합니다. @EnableAutoConfiguration, AutoConfiguration.imports, @Conditional 계열 애노테이션, 사용자 빈 우선 원칙, --debug 모드로 Auto-Configuration 보고서 분석, 그리고 특정 Auto-Configuration을 제외하는 방법까지 실무 중심으로 다룹니다.
지난 글에서 환경별 설정 분리를 위한 Profiles를 다뤘습니다. 이번에는 Spring Boot의 가장 강력한 특징이자 “설정 없이 바로 동작하는” 마법의 근원인 Auto-Configuration 동작 원리를 완전히 해부합니다.
Auto-Configuration이란
spring-boot-starter-web 하나만 의존성에 추가하면 Tomcat이 내장되고, DispatcherServlet이 등록되고, JSON 변환기가 설정됩니다. 이것이 Auto-Configuration입니다.
핵심 원리는 단순합니다. “클래스패스에 특정 라이브러리가 있으면, 그에 맞는 빈을 자동으로 등록한다.” 이 조건부 빈 등록 로직이 수백 개의 @Configuration 클래스에 담겨 있으며, Spring Boot가 기동 시 이를 일괄 처리합니다.
세 단계 동작 흐름
1단계 — 후보 목록 수집
@EnableAutoConfiguration이 트리거가 됩니다. @SpringBootApplication 안에 포함된 이 애노테이션이 활성화되면, Spring Boot는 클래스패스의 모든 JAR에서 Auto-Configuration 클래스 목록을 수집합니다.
- Spring Boot 2.x:
META-INF/spring.factories의EnableAutoConfiguration키 - Spring Boot 3.x:
META-INF/spring/AutoConfiguration.imports파일
2단계 — 조건(@Conditional) 평가
수집된 후보 클래스 각각에 붙은 @Conditional 계열 애노테이션을 평가합니다. 조건이 충족되지 않는 클래스는 건너뜁니다.
3단계 — 빈 등록
모든 조건을 통과한 @Configuration 클래스가 스프링 컨텍스트에 로딩되고, 정의된 빈들이 등록됩니다.
@Conditional 계열 애노테이션
가장 자주 사용되는 조건들입니다.
@AutoConfiguration
@ConditionalOnClass(DataSource.class) // DataSource 클래스가 CP에 있을 때
@ConditionalOnMissingBean(DataSource.class) // DataSource 빈이 아직 없을 때
public class DataSourceAutoConfiguration {
@Bean
@ConditionalOnProperty(
prefix = "spring.datasource", name = "url") // 설정 키가 존재할 때
public DataSource dataSource(DataSourceProperties properties) {
return properties.initializeDataSourceBuilder().build();
}
}
@ConditionalOnMissingBean이 핵심입니다. 사용자가 같은 타입의 빈을 먼저 등록하면 Auto-Configuration의 빈 등록이 건너뜁니다. 이것이 커스터마이징 포인트입니다.
Auto-Configuration 후보 파일 구조
Spring Boot 3.x 기준으로 spring-boot-autoconfigure JAR 내부의 구조를 살펴보면:
META-INF/spring/
└── org.springframework.boot.autoconfigure.AutoConfiguration.imports
이 파일에 Auto-Configuration 클래스들이 줄바꿈으로 구분되어 나열됩니다.
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration
# ... 150개 이상
—debug 모드로 Auto-Configuration 보고서 확인
어떤 Auto-Configuration이 적용됐고 어떤 것이 제외됐는지 확인하려면 --debug 플래그를 사용합니다.
java -jar app.jar --debug
# 또는
./gradlew bootRun --args='--debug'
애플리케이션 로그에 Conditions Evaluation Report가 출력됩니다.
============================
CONDITIONS EVALUATION REPORT
============================
Positive matches: ← 조건 충족, 등록됨
-----------------
DataSourceAutoConfiguration matched:
- @ConditionalOnClass found required classes 'javax.sql.DataSource' (...)
Negative matches: ← 조건 미충족, 건너뜀
-----------------
ActiveMQAutoConfiguration:
- @ConditionalOnClass did not find required class 'javax.jms.ConnectionFactory'
Exclusions: ← 사용자가 명시적으로 제외
-----------
None
이 보고서를 읽으면 “왜 내 설정이 적용되지 않는가”를 빠르게 진단할 수 있습니다.
Auto-Configuration 제외하기
특정 Auto-Configuration이 간섭한다면 명시적으로 제외합니다.
// @SpringBootApplication의 exclude 속성
@SpringBootApplication(
exclude = {
DataSourceAutoConfiguration.class,
SecurityAutoConfiguration.class
}
)
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
또는 application.yml에서:
spring:
autoconfigure:
exclude:
- org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
DataSource 없이 Spring Boot를 구동하거나, Security 자동 설정 대신 직접 설정할 때 자주 씁니다.
사용자 빈이 항상 우선
Auto-Configuration은 항상 사용자 설정보다 나중에 처리됩니다. @AutoConfiguration은 내부적으로 @Configuration(proxyBeanMethods = false)이며, 일반 @Configuration이 먼저 로딩된 후 Auto-Configuration이 처리됩니다.
// 이 빈이 있으면 DataSourceAutoConfiguration의 빈 등록이 건너뜀
@Configuration
public class MyDataSourceConfig {
@Bean
public DataSource dataSource() {
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl("jdbc:mysql://custom-host/mydb");
return ds;
}
}
이 원칙을 이해하면 “Auto-Configuration이 내 설정을 무시한다”는 혼란에서 벗어날 수 있습니다. Auto-Configuration은 기본값 제공자입니다. 사용자 설정이 있으면 겸손하게 물러납니다.
Auto-Configuration 순서 제어
여러 Auto-Configuration 사이의 실행 순서가 중요할 때 @AutoConfigureBefore, @AutoConfigureAfter를 사용합니다.
@AutoConfiguration(after = DataSourceAutoConfiguration.class)
public class JpaRepositoriesAutoConfiguration {
// DataSource가 먼저 등록된 뒤 JPA 설정 진행
}
커스텀 Auto-Configuration 스타터를 만들 때 이 애노테이션으로 의존 관계를 명시합니다.
정리
- Auto-Configuration = 클래스패스 감지 →
@Conditional평가 → 빈 자동 등록 - Boot 3.x:
AutoConfiguration.imports파일이 후보 목록 역할 @ConditionalOnMissingBean이 핵심 — 사용자 빈이 있으면 Auto-Configuration이 물러남--debug플래그로 Conditions Evaluation Report 확인 → 문제 진단 가능exclude속성이나 yml 설정으로 특정 Auto-Configuration 제외 가능
지난 글: Spring Boot Profiles 완전 정복
다음 글: Spring Boot Starter 구조 완전 정복
읽어주셔서 감사합니다. 😊