SpringApplication과 부트스트랩 과정

한눈에 보기

SpringApplication은 스프링 부트의 main 메서드에서 부트스트랩을 총괄하는 클래스다. run() 내부의 환경 준비, 컨텍스트 생성, refresh, 러너 실행 순서와 자동 구성 원리를 설명한다.

최종 업데이트 2026.09.17

SpringApplication은 스프링 부트(Spring Boot) 애플리케이션의 main 메서드에서 부트스트랩(Bootstrap) 과정을 총괄하는 클래스다. SpringApplication.run()을 호출하면 환경 정보 준비, 애플리케이션 컨텍스트(ApplicationContext) 생성, 빈(Bean) 등록과 초기화, 내장 웹 서버 구동까지의 과정이 정해진 순서로 진행된다. 개발자가 서버 설정 없이 main 메서드 하나로 애플리케이션을 띄울 수 있는 이유가 이 클래스에 있다.

SpringApplication의 역할

전통적인 스프링 프레임워크에서는 개발자가 컨텍스트 구현체를 고르고 설정 파일을 지정하며 서블릿 컨테이너에 배포하는 일을 직접 했다. SpringApplication은 이 결정을 대신 내려 준다. 클래스패스(Classpath)를 조사해 서블릿 웹, 리액티브 웹, 비웹 중 애플리케이션 타입을 추론하고, 그에 맞는 컨텍스트 구현체를 고르고, 톰캣(Tomcat) 같은 내장 서버를 함께 띄운다. 전형적인 시작 코드는 다음과 같다.

@SpringBootApplication
public class DevfitApplication {

    public static void main(String[] args) {
        SpringApplication.run(DevfitApplication.class, args);
    }
}

run() 메서드의 내부 동작 순서

run()이 호출되면 크게 다음 단계가 순서대로 실행된다.

  1. 리스너 준비: spring.factories 방식으로 등록된 SpringApplicationRunListeners를 로딩하고 시작 이벤트를 발행한다. 이후 각 단계마다 대응하는 이벤트가 발행되어 확장 지점으로 쓰인다.
  2. Environment 준비: 커맨드라인 인자, 운영체제 환경 변수, application.yml 같은 프로퍼티 소스를 우선순위에 따라 합쳐 Environment 객체를 만들고, 활성 프로파일(Profile)을 결정한다.
  3. 배너 출력: 콘솔에 배너를 출력한다. banner.txt로 교체하거나 끌 수 있다.
  4. 컨텍스트 생성: 추론된 애플리케이션 타입에 맞춰, 서블릿 웹이라면 AnnotationConfigServletWebServerApplicationContext를 생성한다.
  5. 컨텍스트 준비: Environment를 컨텍스트에 연결하고, ApplicationContextInitializer를 실행하며, 메인 설정 클래스를 빈 정의로 등록한다.
  6. refresh 호출: 스프링 컨테이너의 핵심 단계다. 컴포넌트 스캔과 자동 구성으로 모든 빈 정의를 읽고, BeanFactoryPostProcessor와 BeanPostProcessor를 적용하며, 싱글턴(Singleton) 빈을 미리 생성한다. 서블릿 웹 컨텍스트라면 이 단계에서 내장 웹 서버가 만들어지고 포트를 연다.
  7. 러너 실행: 컨텍스트 준비가 끝난 뒤 ApplicationRunner와 CommandLineRunner 빈을 순서대로 실행해 시작 직후 로직을 처리한다.

이 과정에서 실패하면 FailureAnalyzer가 원인을 분석해, 포트 충돌이나 빈 순환 참조 같은 문제를 사람이 읽기 좋은 메시지로 출력한다.

@SpringBootApplication과 자동 구성

부트스트랩의 절반은 자동 구성(Auto Configuration)이 담당한다. @SpringBootApplication은 세 애너테이션의 조합이다.

  • @SpringBootConfiguration: 이 클래스가 설정 클래스임을 나타낸다. @Configuration의 특수화다.
  • @ComponentScan: 해당 클래스가 위치한 패키지부터 하위 패키지까지 @Component 계열 클래스를 찾아 빈으로 등록한다. 메인 클래스를 최상위 패키지에 두는 관례가 여기서 나온다.
  • @EnableAutoConfiguration: 클래스패스에 있는 라이브러리를 근거로 필요한 설정을 자동 등록한다. 후보 목록은 AutoConfiguration.imports 파일에서 읽고, @ConditionalOnClass, @ConditionalOnMissingBean 같은 조건 애너테이션으로 적용 여부를 결정한다.

예를 들어 spring-boot-starter-web이 클래스패스에 있으면 DispatcherServlet과 내장 톰캣 설정이 자동으로 등록되고, 개발자가 같은 타입의 빈을 직접 정의하면 @ConditionalOnMissingBean 조건에 걸려 자동 구성이 물러난다. 사용자 정의가 항상 우선한다는 원칙이 이렇게 구현된다.

부트스트랩 커스터마이징

run()을 호출하기 전에 SpringApplication 인스턴스를 직접 만들면 시작 방식을 조정할 수 있다.

public static void main(String[] args) {
    SpringApplication app = new SpringApplication(DevfitApplication.class);
    app.setBannerMode(Banner.Mode.OFF);          // 배너 끄기
    app.setLazyInitialization(true);             // 빈 지연 초기화
    app.setAdditionalProfiles("local");          // 프로파일 추가
    app.setWebApplicationType(WebApplicationType.SERVLET);
    app.run(args);
}

시작 직후 초기화 작업은 러너로 등록한다.

@Component
public class DataInitRunner implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments args) {
        // 컨텍스트가 완전히 준비된 뒤 실행된다
    }
}

ApplicationRunner는 파싱된 ApplicationArguments를 받고 CommandLineRunner는 원시 문자열 배열을 받는다는 차이만 있으며, 둘 다 @Order로 실행 순서를 지정할 수 있다.

주의할 점

지연 초기화를 켜면 기동 시간은 줄지만, 잘못 설정된 빈의 오류가 기동 시점이 아니라 첫 요청 시점에 드러난다는 트레이드오프가 있다. 또한 시작 시점 로직을 @PostConstruct에 넣으면 다른 빈이 아직 준비되지 않았거나 프록시가 완성되지 않은 상태에서 실행될 수 있으므로, 전체 컨텍스트가 필요한 작업은 러너나 ApplicationReadyEvent 리스너에 두는 편이 안전하다. 기동이 느려졌다면 spring-boot-starter-actuator의 startup 엔드포인트나 BufferingApplicationStartup으로 단계별 소요 시간을 측정해 원인을 찾을 수 있다.

면접에서 이렇게 물어본다

  • SpringApplication.run()이 호출된 뒤 내장 웹 서버가 뜨기까지의 과정을 단계별로 설명해 보라.
  • @SpringBootApplication을 구성하는 세 애너테이션과 각각의 역할을 말해 보라.
  • 자동 구성이 어떤 원리로 동작하며, 개발자가 정의한 빈이 자동 구성보다 우선하는 이유를 설명해 보라.
  • ApplicationRunner와 @PostConstruct 중 시작 시점 초기화 로직을 어디에 두는 것이 안전한지 근거와 함께 말해 보라.
  • 스프링 부트 없이 스프링 프레임워크만 쓸 때와 비교해 부트스트랩 과정에서 무엇이 달라지는지 설명해 보라.
Spring / JPA 문서 전체 보기

이 개념, 내 코드에서는 어떻게 물어볼까요

데브핏(DevFit)에 채용공고 URL을 붙여 넣고 레포지토리를 연결하면, 내가 쓴 커밋에서 예상 질문과 어필 포인트를 만듭니다. 하루 10회까지 무료입니다. 합불 판정이나 지원자 랭킹은 만들지 않고, 최종 판단은 사람이 합니다.

공고 넣고 시작하기