@SpringBootApplication 내부 구조, 한 번이라도 직접 열어본 적 있으신가요? Spring Boot 프로젝트를 시작하면 메인 클래스에 항상 붙어 있는 이 어노테이션, 그냥 “있어야 하는 것”으로만 알고 넘어간 분들이 많습니다. 하지만 면접관이 “이 어노테이션 안에 뭐가 있는지 아세요?”라고 물었을 때, 혹은 자동 설정이 예상대로 동작하지 않아 디버깅해야 할 때, 내부를 모르면 속수무책이 됩니다. 이 글에서는 @SpringBootApplication 하나를 완전히 해부하여 Spring Boot가 단 한 줄로 어떻게 애플리케이션 전체를 구동시키는지 코드와 함께 낱낱이 분석합니다.
목차
- @SpringBootApplication이란 무엇인가 – 기초 개념 정리
- @SpringBootApplication 내부 구조 – 세 어노테이션 해부
- 자동 설정이 가져다주는 효과와 장점
- 자동 설정의 함정과 주의점
- 실전 단계별 활용법 – 커스터마이징과 제어 방법
- 전문가 관점 – 내부 동작 원리와 추천 분석 도구
1. @SpringBootApplication이란 무엇인가 – 기초 개념 정리
Spring Boot 프로젝트를 생성하면 가장 먼저 마주치는 코드가 있습니다.
java
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
단 두 줄의 코드로 내장 톰캣이 실행되고, 수십 개의 빈이 자동 등록되며, 컴포넌트 스캔이 시작됩니다. 마법처럼 느껴지지만, 이 모든 동작의 시작점은 @SpringBootApplication이라는 어노테이션 하나입니다.
메타 어노테이션이란?
@SpringBootApplication을 이해하려면 먼저 메타 어노테이션(Meta-Annotation) 개념을 알아야 합니다. 메타 어노테이션이란 다른 어노테이션을 정의하는 데 사용되는 어노테이션입니다. 즉 @SpringBootApplication은 그 자체가 기능을 갖는 것이 아니라, 내부에 여러 어노테이션을 포함하여 그 기능들을 한 번에 적용하는 합성 어노테이션(Composed Annotation) 입니다.
일상적인 비유를 들면, 종합 비타민 한 알을 먹으면 비타민 A, B, C, D 등이 한꺼번에 섭취되는 것과 같습니다. @SpringBootApplication 하나를 붙이면 내부에 있는 여러 어노테이션의 기능이 모두 적용됩니다.
실제 소스 코드 확인
IntelliJ IDEA에서 @SpringBootApplication 위에 커서를 올리고 Cmd+클릭(Mac) 또는 Ctrl+클릭(Windows)을 하면 실제 소스 코드로 이동할 수 있습니다. Spring Boot 3.x 기준 실제 선언부는 다음과 같습니다.
java
// org.springframework.boot.autoconfigure.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;
}
소스 코드를 보면 핵심이 보입니다. @SpringBootApplication 내부 구조는 크게 세 개의 어노테이션으로 이루어져 있습니다.
@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan
이 세 가지를 하나씩 해부해 보겠습니다.
2. @SpringBootApplication 내부 구조 – 세 어노테이션 해부
① @SpringBootConfiguration – 설정 클래스 선언
java
// org.springframework.boot.SpringBootConfiguration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration // 핵심은 바로 이것
@Indexed
public @interface SpringBootConfiguration {
@AliasFor(annotation = Configuration.class)
boolean proxyBeanMethods() default true;
}
@SpringBootConfiguration은 내부적으로 Spring의 @Configuration을 포함하는 어노테이션입니다. 즉 @SpringBootApplication이 붙은 메인 클래스는 Spring의 설정 클래스(@Configuration) 로 동작합니다.
@Configuration이 붙은 클래스는 Spring IoC 컨테이너가 빈 정의(BeanDefinition)의 소스로 인식합니다. 덕분에 메인 클래스 안에서도 @Bean 메서드를 선언하여 수동으로 빈을 등록할 수 있습니다.
java
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
// 메인 클래스가 @Configuration이므로 @Bean 등록 가능
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
@Configuration vs @SpringBootConfiguration 차이
두 어노테이션의 기능은 거의 동일하지만, @SpringBootConfiguration은 애플리케이션 내에 하나만 존재해야 한다는 제약 조건이 있습니다. Spring Boot의 테스트 유틸리티(@SpringBootTest)는 이 어노테이션을 기준으로 애플리케이션의 메인 설정 클래스를 자동 탐색합니다. 따라서 @SpringBootConfiguration을 여러 클래스에 붙이면 테스트 컨텍스트 로딩 시 충돌이 발생합니다.
proxyBeanMethods 속성의 의미
proxyBeanMethods = true(기본값)이면 @Configuration 클래스가 CGLIB 프록시로 감싸집니다. 이를 통해 @Bean 메서드를 여러 번 호출해도 항상 동일한 싱글톤 인스턴스가 반환됩니다.
java
@SpringBootApplication(proxyBeanMethods = false) // Lite 모드
public class DemoApplication {
@Bean
public ServiceA serviceA() {
return new ServiceA(serviceB()); // proxyBeanMethods=false면 매번 새 인스턴스 생성
}
@Bean
public ServiceB serviceB() {
return new ServiceB();
}
}
proxyBeanMethods = false로 설정하면 CGLIB 프록시를 생성하지 않아 애플리케이션 시작 속도가 빨라지지만, @Bean메서드 간 직접 호출 시 싱글톤이 보장되지 않습니다. 빈 간의 직접 호출이 없는 단순한 설정에서만 사용하세요.
② @EnableAutoConfiguration – 자동 설정의 핵심
@SpringBootApplication 내부 구조에서 가장 핵심적이고 강력한 어노테이션입니다. 이것이 바로 Spring Boot가 “마법처럼” 동작하는 비밀입니다.
java
// org.springframework.boot.autoconfigure.EnableAutoConfiguration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class) // 핵심
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
핵심은 @Import(AutoConfigurationImportSelector.class)입니다.
AutoConfigurationImportSelector의 동작 흐름
① @EnableAutoConfiguration 활성화
↓
② AutoConfigurationImportSelector 실행
↓
③ META-INF/spring/AutoConfiguration.imports 파일 로드
(Spring Boot 2.x: META-INF/spring.factories)
↓
④ 등록된 수백 개의 AutoConfiguration 클래스 후보 목록 수집
↓
⑤ @Conditional 조건 평가 (클래스패스, 빈 존재 여부 등)
↓
⑥ 조건을 통과한 AutoConfiguration만 BeanDefinition으로 등록
AutoConfiguration.imports 파일
Spring Boot 3.x에서는 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 파일에 자동 설정 후보 클래스들이 등록되어 있습니다. 실제 파일을 열어보면 수백 개의 클래스가 줄줄이 나열되어 있습니다.
# 실제 AutoConfiguration.imports 파일 내용 일부
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration
# ... 150개 이상
@Conditional – 조건부 설정 등록
모든 AutoConfiguration이 무조건 적용되면 충돌과 불필요한 빈이 넘쳐날 것입니다. Spring Boot는 @Conditional 시리즈 어노테이션으로 “이 조건을 만족할 때만 이 설정을 적용하라” 는 조건부 등록을 구현합니다.
java
// DataSourceAutoConfiguration 내부 – 단순화한 예시
@AutoConfiguration(before = SqlInitializationAutoConfiguration.class)
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
// 클래스패스에 DataSource 클래스가 있을 때만 활성화
@ConditionalOnMissingBean(type = "io.r2dbc.spi.ConnectionFactory")
// R2DBC ConnectionFactory 빈이 없을 때만 활성화
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ DataSourcePoolMetadataProvidersConfiguration.class,
DataSourceCheckpointRestoreConfiguration.class })
public class DataSourceAutoConfiguration {
@ConditionalOnMissingBean(DataSource.class)
// 개발자가 직접 DataSource 빈을 등록하지 않았을 때만 활성화
@ConditionalOnSingleCandidate(DataSource.class)
static class EmbeddedDatabaseConfiguration {
// H2 인메모리 DB 자동 설정
}
}
주요 @Conditional 어노테이션 목록은 다음과 같습니다.
| 어노테이션 | 조건 |
|---|---|
@ConditionalOnClass | 특정 클래스가 클래스패스에 존재할 때 |
@ConditionalOnMissingClass | 특정 클래스가 클래스패스에 없을 때 |
@ConditionalOnBean | 특정 빈이 이미 등록되어 있을 때 |
@ConditionalOnMissingBean | 특정 빈이 등록되어 있지 않을 때 |
@ConditionalOnProperty | 특정 프로퍼티 값이 조건과 일치할 때 |
@ConditionalOnWebApplication | 웹 애플리케이션 환경일 때 |
@ConditionalOnExpression | SpEL 표현식이 true일 때 |
③ @ComponentScan – 빈 자동 탐색
java
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class)
})
@ComponentScan은 @Component, @Service, @Repository, @Controller, @RestController 등의 어노테이션이 붙은 클래스를 스캔하여 Spring 빈으로 자동 등록하는 역할을 합니다.
기본 스캔 범위
@ComponentScan에 basePackages를 별도로 지정하지 않으면, 이 어노테이션이 붙은 클래스의 패키지와 그 하위 패키지 전체를 스캔합니다.
com.example.demo
├── DemoApplication.java ← @SpringBootApplication 위치
├── controller
│ └── OrderController.java ← 스캔 대상 ✓
├── service
│ └── OrderService.java ← 스캔 대상 ✓
├── repository
│ └── OrderRepository.java ← 스캔 대상 ✓
└── config
└── SecurityConfig.java ← 스캔 대상 ✓
com.other ← 스캔 범위 밖 ✗
이것이 Spring Boot에서 메인 클래스를 루트 패키지에 두어야 하는 이유입니다. 메인 클래스가 하위 패키지에 있으면 상위 패키지의 컴포넌트들이 스캔되지 않아 빈 등록이 누락됩니다.
excludeFilters의 역할
@SpringBootApplication의 @ComponentScan에는 두 가지 제외 필터가 기본으로 걸려 있습니다.
TypeExcludeFilter: 테스트 환경에서 특정 타입을 제외하기 위한 확장 포인트입니다.AutoConfigurationExcludeFilter:@Configuration이면서 동시에AutoConfiguration.imports에 등록된 클래스를 컴포넌트 스캔 대상에서 제외합니다. 자동 설정 클래스들이@ComponentScan과@EnableAutoConfiguration양쪽에서 이중으로 등록되는 것을 방지합니다.
3. 자동 설정이 가져다주는 효과와 장점
@SpringBootApplication 내부 구조를 이루는 세 어노테이션이 맞물려 동작하면서 개발자에게 다음과 같은 실질적인 이점을 제공합니다.
설정 코드의 극적인 감소
Spring Boot 이전에는 웹 애플리케이션 하나를 띄우려면 DispatcherServlet 등록, ViewResolver 설정, MessageConverter 설정, DataSource 빈 등록 등 수십 줄의 설정 코드가 필요했습니다. @EnableAutoConfiguration이 이 모든 것을 조건에 따라 자동으로 처리합니다.
예를 들어 spring-boot-starter-web을 의존성에 추가하는 순간, 클래스패스에 spring-webmvc가 포함되고, WebMvcAutoConfiguration이 @ConditionalOnClass(DispatcherServlet.class) 조건을 만족하여 자동으로 DispatcherServlet, HandlerMapping, HandlerAdapter 등 MVC 동작에 필요한 모든 빈을 등록합니다.
의존성 추가만으로 기능 활성화
xml
<!-- pom.xml에 이것 하나 추가하면 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
위 의존성을 추가하는 것만으로 SecurityAutoConfiguration이 자동 활성화되어 모든 엔드포인트에 HTTP Basic 인증이 적용되고, 기본 사용자 계정이 생성됩니다. 개발자가 별도로 @EnableWebSecurity를 선언하거나 SecurityFilterChain을 구성하면 자동 설정이 뒤로 물러납니다(@ConditionalOnMissingBean 덕분).
환경별 자동 감지
@ConditionalOnProperty를 활용하면 application.yml 설정값에 따라 자동으로 다른 빈이 등록됩니다.
yaml
# application-dev.yml
spring:
datasource:
url: jdbc:h2:mem:testdb # 개발 환경 → H2 자동 설정 활성화
# application-prod.yml
spring:
datasource:
url: jdbc:postgresql://prod-server:5432/mydb # 운영 환경 → PostgreSQL
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
프로파일만 바꿔도 자동 설정이 환경에 맞게 조건부로 적용됩니다. 코드 변경 없이 환경 전환이 가능한 이유가 바로 이 구조 덕분입니다.
빠른 프로토타이핑과 생산성
신규 기능을 빠르게 검증해야 하는 상황에서, 자동 설정 덕분에 핵심 비즈니스 로직만 작성하고 곧바로 실행할 수 있습니다. 스타트업 환경에서 Spring Boot가 압도적으로 채택되는 핵심 이유입니다.
4. 자동 설정의 함정과 주의점
편리함 뒤에는 반드시 이해해야 할 주의점이 따릅니다. 자동 설정의 함정을 모르면 예상치 못한 버그와 보안 취약점이 생깁니다.
의도치 않은 자동 설정 활성화
가장 흔한 문제는 의존성을 추가했을 때 의도하지 않은 자동 설정이 함께 활성화되는 경우입니다.
java
// 보안 취약 예시 – H2 Console이 운영 환경에 노출될 수 있음
// spring-boot-starter-test 의존성에 H2가 포함되어 있고
// spring.h2.console.enabled=true 설정이 있으면
// 운영 환경에서도 H2 Console이 외부에 노출됩니다.
이를 방지하기 위해 불필요한 자동 설정은 명시적으로 제외해야 합니다.
java
// 방법 1 – @SpringBootApplication exclude 속성 사용
@SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class,
SecurityAutoConfiguration.class
})
public class DemoApplication { ... }
// 방법 2 – application.yml에서 제외
yaml
spring:
autoconfigure:
exclude:
- org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
- org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration
자동 설정 충돌 – “Expected single matching bean but found 2”
인터페이스의 구현체가 두 개 이상 빈으로 등록되면 Spring이 어떤 빈을 주입해야 할지 판단하지 못해 NoUniqueBeanDefinitionException이 발생합니다.
java
// 문제 상황: DataSource 구현체가 두 개
@Bean
public DataSource customDataSource() { ... } // 개발자가 직접 등록
// DataSourceAutoConfiguration도 DataSource를 등록하려 함 → 충돌!
// 해결책: @ConditionalOnMissingBean 덕분에 개발자 빈이 우선
// 자동 설정은 @ConditionalOnMissingBean(DataSource.class)를 달고 있어
// 개발자가 DataSource를 직접 등록하면 자동 설정이 스스로 물러납니다
직접 빈을 등록할 때는 자동 설정이 @ConditionalOnMissingBean으로 물러나는 구조를 이해하고 있어야 충돌 원인을 빠르게 파악할 수 있습니다.
메인 클래스 패키지 위치 오류
// 잘못된 구조 – 컴포넌트 스캔 범위 밖에 컨트롤러 위치
com.example
└── DemoApplication.java ← 메인 클래스
com.example.demo ← 메인 클래스보다 하위가 아닌 별도 패키지?
└── OrderController.java ← 스캔 안 됨!
// 올바른 구조
com.example.demo
├── DemoApplication.java ← 루트에 위치
├── controller
│ └── OrderController.java ← 하위 패키지, 스캔 O
└── service
└── OrderService.java ← 하위 패키지, 스캔 O
@ComponentScan이 메인 클래스의 패키지를 기준으로 하위를 스캔하기 때문에, 메인 클래스가 루트 패키지에 없으면 일부 컴포넌트가 스캔되지 않아 404, NoSuchBeanDefinitionException 오류가 발생합니다.
자동 설정 과의존으로 인한 내부 원리 무지
자동 설정만 믿고 내부 동작을 이해하지 않으면, 설정을 커스터마이징해야 하거나 장애가 발생했을 때 원인을 찾지 못합니다. “왜 갑자기 Thymeleaf 설정이 적용 안 되지?”, “왜 SecurityFilterChain이 두 개 생기지?” 같은 문제의 원인은 항상 자동 설정의 조건(@Conditional)을 이해하는 것에서 출발합니다.
5. 실전 단계별 활용법 – 커스터마이징과 제어 방법
Step 1. 자동 설정 목록 확인하기
현재 애플리케이션에 어떤 자동 설정이 적용되고 있는지 확인하는 방법은 두 가지입니다.
방법 1 – debug 모드 실행
yaml
# application.yml
debug: true
애플리케이션 시작 시 콘솔에 Conditions Report가 출력됩니다. 어떤 자동 설정이 활성화되었고(Positive matches), 어떤 것이 제외되었는지(Negative matches) 한눈에 확인할 수 있습니다.
============================
CONDITIONS EVALUATION REPORT
============================
Positive matches:
-----------------
DataSourceAutoConfiguration matched:
- @ConditionalOnClass found required classes 'javax.sql.DataSource' (OnClassCondition)
WebMvcAutoConfiguration matched:
- @ConditionalOnClass found required classes 'Servlet', 'DispatcherServlet' (OnClassCondition)
- @ConditionalOnWebApplication (required) found 'session' scope (OnWebApplicationCondition)
Negative matches:
-----------------
MongoAutoConfiguration:
- @ConditionalOnClass did not find required class 'com.mongodb.MongoClient' (OnClassCondition)
방법 2 – Actuator /actuator/conditions 엔드포인트
yaml
management:
endpoints:
web:
exposure:
include: conditions, beans, env
http://localhost:8080/actuator/conditions에 접속하면 JSON 형태로 자동 설정 조건 평가 결과를 확인할 수 있습니다.
Step 2. 자동 설정 오버라이드하기
자동 설정이 제공하는 기본값이 마음에 들지 않을 때 개발자가 직접 빈을 등록하면 자동 설정이 물러납니다.
java
// WebMvcAutoConfiguration이 제공하는 기본 MessageConverter 대신
// 커스텀 MessageConverter를 등록하는 예시
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
// 기본 설정을 완전히 교체
converters.add(new MappingJackson2HttpMessageConverter(customObjectMapper()));
}
@Bean
public ObjectMapper customObjectMapper() {
return new ObjectMapper()
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
}
}
Step 3. 나만의 AutoConfiguration 만들기
내부 라이브러리나 공통 모듈을 만들 때 자동 설정을 직접 구현할 수 있습니다.
java
// 커스텀 AutoConfiguration 클래스
@AutoConfiguration
@ConditionalOnClass(CustomService.class)
@ConditionalOnMissingBean(CustomService.class)
@EnableConfigurationProperties(CustomProperties.class)
public class CustomAutoConfiguration {
@Bean
public CustomService customService(CustomProperties properties) {
return new CustomService(properties.getApiKey(), properties.getTimeout());
}
}
java
// 설정 프로퍼티 클래스
@ConfigurationProperties(prefix = "custom.service")
public class CustomProperties {
private String apiKey;
private int timeout = 30;
// getter, setter
}
# META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.example.config.CustomAutoConfiguration
META-INF/spring/AutoConfiguration.imports 파일에 클래스명을 등록하면, 이 라이브러리를 의존성으로 추가하는 모든 Spring Boot 프로젝트에서 자동으로 설정이 적용됩니다.
Step 4. @ComponentScan 범위 직접 지정하기
java
// 특정 패키지만 스캔하거나 특정 어노테이션을 가진 클래스만 포함/제외
@SpringBootApplication(scanBasePackages = {
"com.example.service",
"com.example.repository",
"com.example.controller"
})
public class DemoApplication { ... }
// 또는 타입 세이프하게 클래스 기준으로 지정
@SpringBootApplication(scanBasePackageClasses = {
OrderService.class,
UserController.class
})
public class DemoApplication { ... }
멀티 모듈 프로젝트에서 특정 모듈만 스캔 범위에 포함하거나 제외할 때 유용합니다.
6. 전문가 관점 – 내부 동작 원리와 추천 분석 도구
SpringApplication.run()과의 관계
@SpringBootApplication 내부 구조를 완전히 이해하려면 SpringApplication.run()이 이 어노테이션을 어떻게 처리하는지도 알아야 합니다.
SpringApplication.run(DemoApplication.class, args)
│
├── ① SpringApplication 객체 생성
│ - 웹 애플리케이션 타입 감지 (SERVLET / REACTIVE / NONE)
│ - ApplicationContextInitializer 로드
│ - ApplicationListener 로드
│
├── ② 애플리케이션 컨텍스트 생성
│ - AnnotationConfigServletWebServerApplicationContext 생성
│
├── ③ @SpringBootApplication 처리
│ ├── @SpringBootConfiguration → 설정 클래스로 등록
│ ├── @ComponentScan → 하위 패키지 컴포넌트 탐색 및 BeanDefinition 등록
│ └── @EnableAutoConfiguration → AutoConfigurationImportSelector 실행
│ → 조건 평가 후 AutoConfiguration 적용
│
├── ④ 빈 생성 및 의존성 주입
│
├── ⑤ 내장 서버 시작 (Tomcat/Jetty/Undertow)
│
└── ⑥ ApplicationRunner, CommandLineRunner 실행
추천 분석 도구
| 도구 | 용도 | 사용 방법 |
|---|---|---|
| IntelliJ IDEA – Navigate to Source | 어노테이션 소스 직접 탐색 | Cmd/Ctrl + 클릭 |
| Spring Boot Actuator | 자동 설정 조건 런타임 확인 | /actuator/conditions, /actuator/beans |
--debug 플래그 | 시작 시 Conditions Report 출력 | java -jar app.jar --debug |
| Spring Boot 공식 GitHub | AutoConfiguration 소스 확인 | github.com/spring-projects/spring-boot |
| Dependency Analyzer (IDEA) | 클래스패스 의존성 시각화 | Maven/Gradle 탭 활용 |
자동 설정 소스 직접 읽는 습관
자동 설정 문제를 빠르게 해결하는 가장 효과적인 방법은 실제 AutoConfiguration 소스를 직접 읽는 것입니다. IntelliJ에서 Shift 두 번 → 클래스명 검색(예: WebMvcAutoConfiguration)으로 즉시 소스를 열 수 있습니다. 각 @ConditionalOn* 어노테이션을 확인하면 “왜 이 설정이 적용됐는지/안 됐는지”를 논리적으로 추론할 수 있습니다.
면접 대비 핵심 답변
“@SpringBootApplication은 어떤 어노테이션으로 구성되어 있나요?” @SpringBootConfiguration, @EnableAutoConfiguration, @ComponentScan 세 가지 어노테이션의 합성입니다. @SpringBootConfiguration은 설정 클래스를 선언하고, @EnableAutoConfiguration은 클래스패스를 분석해 조건부로 자동 설정을 적용하며, @ComponentScan은 메인 클래스 패키지를 기준으로 컴포넌트를 탐색합니다.
“자동 설정이 어떻게 동작하나요?” @EnableAutoConfiguration이 AutoConfigurationImportSelector를 통해 AutoConfiguration.imports 파일에 등록된 후보 클래스들을 로드합니다. 각 클래스에 붙은 @ConditionalOnClass, @ConditionalOnMissingBean 등의 조건을 평가하여 조건을 만족하는 자동 설정만 실제로 적용됩니다.
결론
@SpringBootApplication은 단순한 어노테이션이 아닙니다. @SpringBootConfiguration으로 설정 클래스를 선언하고, @EnableAutoConfiguration으로 클래스패스를 분석해 조건부 자동 설정을 적용하며, @ComponentScan으로 컴포넌트를 자동 탐색하는 세 축이 맞물려 Spring Boot 애플리케이션 전체를 구동합니다. @SpringBootApplication 내부 구조를 이해하면 자동 설정 문제를 스스로 디버깅할 수 있고, 커스터마이징과 최적화를 자신 있게 할 수 있습니다. 지금 바로 IntelliJ에서 @SpringBootApplication을 클릭하여 소스를 직접 열어보고, debug: true 옵션으로 어떤 자동 설정이 활성화되는지 눈으로 확인해 보세요.
답글 남기기