SpringApplication

SpringApplication (애플리케이션 실행)

Spring Boot 애플리케이션은 main 메서드 하나로 시작돼요. SpringApplication.run()을 호출하면 스프링 컨텍스트를 만들고, 내장 서버를 띄우고, 배너를 출력하는 일련의 시작 과정을 한 번에 처리해요. 이 글에서는 그 시작 흐름을 좀 더 세밀하게 조정하는 방법, 즉 시작 로그·실패 분석·지연 초기화·배너 등을 다룰게요.

출처: SpringApplication (Spring Boot Reference Documentation)

기본 실행

가장 단순한 형태는 @SpringBootApplication을 붙인 클래스에서 SpringApplication.run()을 호출하는 거예요.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MyApplication {

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

기본적으로 INFO 레벨의 로그가 시작 상세(실행 사용자, 사용 중인 자바 버전, PID, 시작 시간 등)와 함께 출력돼요. 다른 레벨이 필요하면 로그 레벨을 설정하면 되고, 시작 정보 로그는 spring.main.log-startup-infofalse로 두면 끌 수 있어요. 이 값이 꺼지면 활성 프로파일 로그도 함께 사라져요.

시작 실패 대응

시작에 실패하면 등록된 FailureAnalyzer 빈들이 전용 오류 메시지와 구체적인 해결 액션을 만들어 줘요. 예를 들어 8080 포트가 이미 사용 중이면 "Port 8080 was already in use" 같은 안내와 함께 원인·해결책이 프레임 형태로 출력돼요. java -jar로 실행할 때는 --debug를 붙여 디버그 로그를 볼 수도 있어요.

지연 초기화 (Lazy Initialization)

SpringApplication은 애플리케이션을 지연 초기화하도록 설정할 수 있어요. 켜면 빈이 시작 시점이 아니라 필요할 때 생성되므로, 웹 애플리케이션은 HTTP 요청이 들어올 때까지 많은 웹 관련 빈이 초기화되지 않아 시작 시간이 줄어요.

다만 지연 초기화는 문제 발견을 늦출 수 있어요. 잘못 설정된 빈이 늦게 초기화되면 시작 시 실패하지 않고 처음 사용될 때 실패하죠. 또 JVM 메모리가 시작 시 초기화되는 빈뿐 아니라 모든 빈을 담을 만큼 충분한지도 확인해야 해요. 그래서 지연 초기화는 기본값이 아니고, 켜기 전에 JVM 힙 크기를 세밀하게 조정하는 걸 권장해요.

spring:
  main:
    lazy-initialization: true

프로그래밍으로는 SpringApplicationBuilder.lazyInitialization() 또는 SpringApplication.setLazyInitialization()으로 켤 수 있어요. 애플리케이션 전체는 지연 초기화를 쓰면서 특정 빈만 즉시 만들고 싶다면 그 빈의 lazy 속성을 @Lazy(false)로 명시하면 돼요.

배너 커스터마이징

시작 시 출력되는 배너는 클래스패스의 banner.txtspring.banner.location 프로퍼티가 가리키는 파일로 바꿀 수 있어요. 파일 인코딩이 UTF-8이 아니라면 spring.banner.charset을 지정하세요.

banner.txt 안에서는 Environment의 모든 키와 함께 다음과 같은 플레이스홀더를 쓸 수 있어요.

변수 설명
${application.title} MANIFEST.MF에 선언된 애플리케이션 제목
${application.version} MANIFEST.MFImplementation-Version 등 애플리케이션 버전
${application.formatted-version} 괄호와 함께 v를 붙여 표시한 버전, 예를 들어 (v1.0)
${spring-boot.version} 사용 중인 Spring Boot 버전, 예를 들어 4.1.0
${spring-boot.formatted-version} 괄호와 v로 포맷한 Spring Boot 버전
${Ansi.NAME} ANSI 이스케이프 코드 이름

spring.main.banner-mode로 배너를 콘솔(console)·로거(log)로 보낼지, 아예 생략(off)할지 정할 수 있어요. 출력된 배너는 springBootBanner라는 이름의 싱글턴 빈으로 등록돼요. application.title·application.version·application.formatted-versionjava -jar 또는 Spring Boot 런처로 실행할 때만 값이 풀리니 참고하세요.

SpringApplication 커스터마이징

기본값이 마음에 안 들면 로컬 인스턴스를 만들어 직접 조정할 수 있어요. 예를 들어 배너를 끄고 싶다면 다음과 같이 작성해요.

import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(MyApplication.class);
        application.setBannerMode(Banner.Mode.OFF);
        application.run(args);
    }
}

SpringApplication 생성자에 넘긴 인자는 빈의 설정 원천이에요. 대개 @Configuration 클래스 참조지만, @Component 클래스를 직접 넘길 수도 있어요. 전체 옵션 목록은 SpringApplication API 문서를 보면 돼요.

버추얼 스레드

버추얼 스레드는 Java 21 이상에서 쓸 수 있고, Java 24 이상을 강력히 권장해요. 활성화는 spring.threads.virtual.enabledtrue로 설정하면 돼요. 켜면 스레드 풀을 설정하는 프로퍼티는 더 이상 효과가 없어요. 버추얼 스레드는 스레드 풀이 아니라 JVM 전체 플랫폼 스레드 풀에 스케줄링되기 때문이죠.

버추얼 스레드는 데몬 스레드라서, 모든 스레드가 데몬이면 JVM이 종료될 수 있어요. @Scheduled 빈으로 애플리케이션을 살려 두는 패턴에 의존한다면 spring.main.keep-alivetrue로 설정해 JVM을 유지하는 걸 권장해요.

알아두면 좋은 점

  • 애플리케이션이 실제로 어떤 HTTP 포트에서 도는지 알고 싶으면 local.server.port 키의 프로퍼티를 읽으면 돼요.
  • runApplication<MyApplication>(*args) 형태로 (코틀린에서) 간결하게 실행할 수도 있어요.

더 알아보기 (Learn more)