이 글에서 얻는 것
- Spring Boot “자동 설정”이 정확히 무엇인지(어디서/어떤 조건으로/왜 등록되는지) 설명할 수 있습니다.
- “내가 만든 빈이 왜 안 먹지?”, “왜 갑자기 Security가 켜졌지?” 같은 문제를 조건 리포트로 디버깅할 수 있습니다.
- 자동 설정을 끄기(exclude)보다 확장/오버라이드로 안전하게 커스터마이징하는 방법을 익힙니다.
0) 자동 설정(Auto-Configuration)은 한 문장으로
Spring Boot는 클래스패스(의존성)와 설정 프로퍼티를 보고,
필요한 @Configuration들을 자동으로 import 해서 “기본 동작”을 만들어줍니다.
중요한 포인트는 “자동 설정은 마법”이 아니라 그냥 조건부로 등록되는 설정 클래스 집합이라는 점입니다.
1) 동작 흐름(큰 그림)
1-1) @SpringBootApplication에서 시작
@SpringBootApplication은 대략 아래를 묶은 편의 어노테이션입니다.
@SpringBootConfiguration(=@Configuration)@ComponentScan@EnableAutoConfiguration
1-2) AutoConfigurationImportSelector가 자동 설정 클래스를 모음
부트는 “자동 설정 목록 파일”을 읽어서 자동 설정 클래스를 가져온 뒤,
각 설정 클래스의 조건(@Conditional*)을 평가해 적용 여부를 결정합니다.
참고(버전 차이):
- Boot 2.x: 주로
META-INF/spring.factories를 통해EnableAutoConfiguration목록을 로딩 - Boot 3.x: 자동 설정 목록이
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports로 이동(성능/구조 개선)
2) 조건부 등록의 핵심: @Conditional*
자동 설정이 “항상 켜지는” 게 아닌 이유는 대부분 여기에 있습니다.
자주 보는 조건:
@ConditionalOnClass: 특정 클래스가 클래스패스에 있으면 켬(= 의존성 추가가 기능 활성화로 이어짐)@ConditionalOnMissingBean: 같은 타입/이름의 빈이 없을 때만 기본 빈을 제공(= 사용자가 오버라이드 가능)@ConditionalOnProperty: 프로퍼티가 특정 값일 때만 활성화@ConditionalOnBean: 특정 빈이 이미 있을 때만 활성화(조합)@ConditionalOnWebApplication: 웹 환경에서만 활성화
3) “내가 만든 설정이 왜 안 먹지?” 디버깅 루틴
자동 설정은 조건 때문에 켜지거나 꺼집니다. 추측하지 말고 조건 리포트를 확인하면 빠릅니다.
3-1) --debug로 ConditionEvaluationReport 보기
실행 옵션에 --debug를 주면 어떤 자동 설정이 “왜 켜졌고/왜 꺼졌는지”가 출력됩니다.
3-2) Actuator의 conditions/beans 활용
운영/로컬에서 원인 추적이 필요하면:
/actuator/conditions: 조건 평가 결과/actuator/beans: 빈 목록과 의존성
(노출은 반드시 인증/내부망 등으로 제한해야 합니다.)
4) 커스터마이징의 우선순위: exclude는 마지막 카드
4-1) 1순위: 프로퍼티로 동작을 조정
자동 설정은 보통 “기본값”을 제공하고, 프로퍼티로 동작을 바꿀 수 있게 설계되어 있습니다.
예:
- DataSource, Jackson, Logging, Management(Actuator) 등은 프로퍼티로 조정 가능한 범위가 큽니다.
4-2) 2순위: 빈 오버라이드(같은 타입 빈 등록)
자동 설정이 @ConditionalOnMissingBean으로 기본 빈을 제공하는 경우,
같은 타입 빈을 직접 등록하면 “내 빈이 우선”이 됩니다.
@Configuration
public class MyConfig {
@Bean
public ObjectMapper objectMapper() {
return new ObjectMapper().findAndRegisterModules();
}
}
4-3) 3순위: 확장 포인트를 사용(커스터마이저/빌더)
부트는 아예 확장용 타입을 제공하는 경우가 많습니다.
WebMvcConfigurer,Jackson2ObjectMapperBuilderCustomizer같은 커스터마이저- Converter/Formatter 등록 등
4-4) 마지막: exclude
자동 설정 제외는 빠르지만 부작용이 큽니다. 다른 자동 설정이 연쇄적으로 기대하는 빈이 사라질 수 있습니다.
정말 필요할 때만 사용합니다.
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
또는:
@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
public class App {}
5) 실무에서 자주 겪는 함정
- 의존성(starter)을 추가했더니 기능이 “자동으로 켜짐” →
@ConditionalOnClass가 원인인 경우가 많음 - 같은 타입 빈이 여러 개라서 주입이 모호함 →
@Primary/@Qualifier로 의도를 명확히 - exclude로 급하게 껐는데 다른 설정이 깨짐 → 우선 프로퍼티/오버라이드/확장으로 해결 가능한지 확인
연습(추천)
spring-boot-starter-security를 추가했을 때 어떤 자동 설정이 켜지는지--debug로 확인해보기- ObjectMapper를 커스터마이징하고, 자동 설정 기본값과 무엇이 달라졌는지 비교해보기
- “의도치 않은 빈 생성”을 일부러 만들어보고(
/actuator/beans,/actuator/conditions), 원인을 추적해보기
💬 댓글