https://docs.spring.io/spring-boot/api/java/org/springframework/boot/SpringApplication.html
https://docs.spring.io/spring-boot/reference/features/spring-application.html
SpringApplication :: Spring Boot
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,
docs.spring.io
SpringApplication
SpringApplication 클래스는 main() 메서드에서 시작되는 Spring 애플리케이션을 부트스트랩하는 편리한 방법을 제공합니다. 다음 예제와 같이 많은 상황에서 정적 SpringApplication.run(Class, String...) 메서드로 위임할 수 있습니다:
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
애플리케이션이 시작되면 다음 출력과 비슷한 내용이 표시됩니다:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.4.1)
2024-12-19T12:20:12.332Z INFO 126957 --- [ main] o.s.b.d.f.logexample.MyApplication : Starting MyApplication using Java 17.0.13 with PID 126957 (/opt/apps/myapp.jar started by myuser in /opt/apps/)
2024-12-19T12:20:12.338Z INFO 126957 --- [ main] o.s.b.d.f.logexample.MyApplication : No active profile set, falling back to 1 default profile: "default"
2024-12-19T12:20:15.485Z INFO 126957 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http)
2024-12-19T12:20:15.549Z INFO 126957 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2024-12-19T12:20:15.552Z INFO 126957 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.34]
2024-12-19T12:20:15.725Z INFO 126957 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2024-12-19T12:20:15.734Z INFO 126957 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3258 ms
2024-12-19T12:20:17.301Z INFO 126957 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/'
2024-12-19T12:20:17.340Z INFO 126957 --- [ main] o.s.b.d.f.logexample.MyApplication : Started MyApplication in 6.042 seconds (process running for 6.85)
2024-12-19T12:20:17.366Z INFO 126957 --- [ionShutdownHook] o.s.b.w.e.tomcat.GracefulShutdown : Commencing graceful shutdown. Waiting for active requests to complete
기본적으로 애플리케이션을 실행한 사용자 등 일부 관련 시작 세부 정보를 포함한 INFO 로깅 메시지가 표시됩니다. INFO 이외의 로그 레벨이 필요한 경우 로그 레벨에 설명된 대로 설정할 수 있습니다. 애플리케이션 버전은 기본 애플리케이션 클래스의 패키지에서 구현 버전을 사용하여 결정됩니다. spring.main.log-startup-info를 false로 설정하여 시작 정보 로깅을 해제할 수 있습니다. 이렇게 하면 애플리케이션의 활성 프로파일에 대한 로깅도 해제됩니다.
TIP
To add additional logging during startup, you can override logStartupInfo(boolean)in a subclass of SpringApplication. |
Startup Failure
애플리케이션이 시작되지 않는 경우, 등록된 FailureAnalyzer 빈은 전용 오류 메시지와 문제 해결을 위한 구체적인 조치를 제공할 기회를 얻습니다. 예를 들어 포트 8080에서 웹 애플리케이션을 시작했는데 해당 포트가 이미 사용 중인 경우 다음 메시지와 비슷한 내용이 표시됩니다:
***************************
APPLICATION FAILED TO START
***************************
Description:
Embedded servlet container failed to start. Port 8080 was already in use.
Action:
Identify and stop the process that is listening on port 8080 or configure this application to listen on another port.
Spring Boot provides numerous FailureAnalyzer implementations, and you can add your own. |
장애 분석기가 예외를 처리할 수 없는 경우에도 전체 조건 보고서를 표시하여 무엇이 잘못되었는지 더 잘 이해할 수 있습니다. 이렇게 하려면 debug 속성을 활성화하거나 ConditionEvaluationReportLoggingListener에 대해 DEBUG 로깅을 활성화해야 합니다.
예를 들어, java -jar를 사용하여 애플리케이션을 실행하는 경우 다음과 같이 디버그 속성을 활성화할 수 있습니다:
$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug
Lazy Initialization
SpringApplication을 사용하면 애플리케이션을 느리게 초기화할 수 있습니다. 지연 초기화를 활성화하면 애플리케이션을 시작하는 동안이 아니라 필요할 때마다 빈이 생성됩니다. 따라서 지연 초기화를 활성화하면 애플리케이션을 시작하는 데 걸리는 시간을 줄일 수 있습니다. 웹 애플리케이션에서 지연 초기화를 활성화하면 HTTP 요청이 수신될 때까지 많은 웹 관련 빈이 초기화되지 않습니다.
지연 초기화의 단점은 애플리케이션의 문제 발견이 지연될 수 있다는 것입니다. 잘못 구성된 빈을 느리게 초기화하면 시작 중에 오류가 더 이상 발생하지 않고 빈이 초기화될 때만 문제가 드러나게 됩니다. 또한 시작 중에 초기화되는 빈뿐만 아니라 애플리케이션의 모든 빈을 수용할 수 있는 충분한 메모리가 JVM에 있는지 확인해야 합니다. 이러한 이유로 지연 초기화는 기본적으로 활성화되지 않으며, 지연 초기화를 활성화하기 전에 JVM의 힙 크기를 미세 조정하는 것이 좋습니다.
지연 초기화는 SpringApplicationBuilder의 lazyInitialization 메서드 또는 SpringApplication의 setLazyInitialization 메서드를 사용하여 프로그래밍 방식으로 활성화할 수 있습니다. 또는 다음 예제와 같이 spring.main.lazy-initialization 속성을 사용하여 활성화할 수 있습니다:
// properties.yml
spring.main.lazy-initialization=true
애플리케이션의 나머지 부분에는 지연 초기화를 사용하면서 특정 빈에 대해 지연 초기화를 사용하지 않으려면 @Lazy(false) 어노테이션을 사용하여 해당 빈의 지연 속성을 명시적으로 false로 설정하면 됩니다.
Customizing the Banner
banner.txt 파일 내에서 환경 설정에서 사용 가능한 모든 키와 다음 자리 표시자를 사용할 수 있습니다:
Table 1. Banner variablesVariableDescription
${application.version} | The version number of your application, as declared in MANIFEST.MF. For example, Implementation-Version: 1.0 is printed as 1.0. |
${application.formatted-version} | The version number of your application, as declared in MANIFEST.MF and formatted for display (surrounded with brackets and prefixed with v). For example (v1.0). |
${spring-boot.version} | The Spring Boot version that you are using. For example 3.4.1. |
${spring-boot.formatted-version} | The Spring Boot version that you are using, formatted for display (surrounded with brackets and prefixed with v). For example (v3.4.1). |
${Ansi.NAME} (or ${AnsiColor.NAME}, ${AnsiBackground.NAME}, ${AnsiStyle.NAME}) | Where NAME is the name of an ANSI escape code. See AnsiPropertySource for details. |
${application.title} | The title of your application, as declared in MANIFEST.MF. For example Implementation-Title: MyApp is printed as MyApp. |
The SpringApplication.setBanner(…) method can be used if you want to generate a banner programmatically. Use the Banner interface and implement your own printBanner() method. |
또한 spring.main.banner-mode 속성을 사용하여 배너를 System.out(콘솔)에 인쇄할지, 구성된 로거(로그)로 보낼지 또는 전혀 생성하지 않을지(꺼짐)를 결정할 수 있습니다.
인쇄된 배너는 springBootBanner라는 이름으로 싱글톤 빈으로 등록됩니다.
application.title, application.version 및 application.formatted-version 속성은 Spring Boot 런처와 함께 java -jar 또는 java -cp를 사용하는 경우에만 사용할 수 있습니다. 압축을 푼 jar를 실행하고 java -cp <classpath> <mainclass>로 시작하거나 애플리케이션을 네이티브 이미지로 실행하는 경우에는 해당 값이 확인되지 않습니다.
속성을 사용하려면 java -jar를 사용하여 애플리케이션을 패킹된 jar로 실행하거나 java org.springframework.boot.loader.launch.JarLauncher를 사용하여 언패킹된 jar로 실행합니다. 이렇게 하면 애플리케이션이 초기화됩니다. 클래스 경로를 빌드하고 앱을 실행하기 전에 배너 속성을 초기화합니다. |
Customizing SpringApplication
스프링 애플리케이션의 기본값이 마음에 들지 않으면 대신 로컬 인스턴스를 만들어 사용자 지정할 수 있습니다. 예를 들어 배너를 끄려면 다음과 같이 작성할 수 있습니다:
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(MyApplication.class);
application.setBannerMode(Banner.Mode.OFF);
application.run(args);
}
}
The constructor arguments passed to SpringApplication are configuration sources for Spring beans. In most cases, these are references to @Configuration classes, but they could also be direct references @Component classes.
application.properties 파일을 사용하여 SpringApplication을 구성할 수도 있습니다. 자세한 내용은 외부화된 구성을 참조하세요.
구성 옵션의 전체 목록은 SpringApplication API 설명서를 참조하세요. (SpringApplication)
Fluent Builder API
ApplicationContext 계층(부모/자식 관계가 있는 여러 컨텍스트)을 빌드해야 하거나 유창한 빌더 API를 선호하는 경우 SpringApplicationBuilder를 사용할 수 있습니다.
SpringApplicationBuilder를 사용하면 다음 예시와 같이 여러 메서드 호출을 함께 연결할 수 있으며 계층을 생성할 수 있는 부모 및 자식 메서드가 포함되어 있습니다:
new SpringApplicationBuilder().sources(Parent.class)
.child(Application.class)
.bannerMode(Banner.Mode.OFF)
.run(args);
There are some restrictions when creating an ApplicationContext hierarchy. For example, Web components must be contained within the child context, and the same Environment is used for both parent and child contexts. See the SpringApplicationBuilder API documentation for full details.
Application Availability
또한 애플리케이션 가용성 인터페이스를 자체 빈에 주입하여 가용성 상태를 얻을 수도 있습니다.
Liveness State
애플리케이션의 “Liveness” 상태는 애플리케이션의 내부 상태가 올바르게 작동할 수 있는지 또는 현재 장애가 발생한 경우 자체적으로 복구할 수 있는지를 알려줍니다. “Liveness” 상태가 중단되면 애플리케이션이 복구할 수 없는 상태에 있으며 인프라에서 애플리케이션을 다시 시작해야 한다는 의미입니다.
In general, the "Liveness" state should not be based on external checks, such as health checks. If it did, a failing external system (a database, a Web API, an external cache) would trigger massive restarts and cascading failures across the platform.
Spring Boot 애플리케이션의 내부 상태는 대부분 Spring ApplicationContext로 표현됩니다. 애플리케이션 컨텍스트가 성공적으로 시작되면 Spring Boot는 애플리케이션이 유효한 상태라고 가정합니다. 애플리케이션은 컨텍스트가 새로 고쳐지는 즉시 라이브 상태로 간주됩니다(Spring Boot 애플리케이션 수명 주기 및 관련 애플리케이션 이벤트를 참조하세요).
Readiness State
애플리케이션 및 명령줄 러너가 호출되는 즉시 애플리케이션이 준비된 것으로 간주되며, Spring Boot 애플리케이션 수명 주기 및 관련 애플리케이션 이벤트를 참조하세요.
Tasks expected to run during startup should be executed by CommandLineRunner and ApplicationRunner components instead of using Spring component lifecycle callbacks such as @PostConstruct
Managing the Application Availability State
애플리케이션 컴포넌트는 ApplicationAvailability 인터페이스를 삽입하고 메서드를 호출하여 언제든지 현재 가용성 상태를 검색할 수 있습니다. 애플리케이션은 상태 업데이트를 수신하거나 애플리케이션의 상태를 업데이트하고자 하는 경우가 많습니다.
예를 들어, 애플리케이션의 “Readiness” 상태를 파일로 내보내서 Kubernetes “실행 프로브”가 이 파일을 볼 수 있도록 할 수 있습니다:
@Component
public class MyReadinessStateExporter {
@EventListener
public void onStateChange(AvailabilityChangeEvent<ReadinessState> event) {
switch (event.getState()) {
case ACCEPTING_TRAFFIC -> {
// create file /tmp/healthy
}
case REFUSING_TRAFFIC -> {
// remove file /tmp/healthy
}
}
}
}
또한 애플리케이션이 중단되어 복구할 수 없는 경우 애플리케이션의 상태를 업데이트할 수도 있습니다:
@Component
public class MyLocalCacheVerifier {
private final ApplicationEventPublisher eventPublisher;
public MyLocalCacheVerifier(ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
public void checkLocalCache() {
try {
// ...
}
catch (CacheCompletelyBrokenException ex) {
AvailabilityChangeEvent.publish(this.eventPublisher, ex, LivenessState.BROKEN);
}
}
}
Spring Boot는 액추에이터 상태 엔드포인트와 함께 “활성” 및 “준비 상태”에 대한 Kubernetes HTTP 프로브를 제공합니다. 전용 섹션에서 Kubernetes에 Spring Boot 애플리케이션을 배포하는 방법에 대한 자세한 지침을 확인할 수 있습니다.
Application Events and Listeners
일반적인 Spring 프레임워크 이벤트(예: ContextRefreshedEvent) 외에도 SpringApplication은 몇 가지 추가 애플리케이션 이벤트를 전송합니다.
일부 이벤트는 실제로 ApplicationContext가 생성되기 전에 트리거되므로 해당 이벤트에 대한 리스너를 @Bean으로 등록할 수 없습니다. SpringApplication.addListeners(...) 메서드 또는 SpringApplicationBuilder.listeners(...) 메서드를 사용하여 등록할 수 있습니다. 애플리케이션이 생성되는 방식에 관계없이 해당 리스너가 자동으로 등록되도록 하려면 다음 예제와 같이 프로젝트에 META-INF/spring.factories 파일을 추가하고 ApplicationListener 키를 사용하여 리스너를 참조할 수 있습니다:
org.springframework.context.ApplicationListener=com.example.project.MyListener
애플리케이션 이벤트는 애플리케이션 실행에 따라 다음 순서로 전송됩니다:
- ApplicationStartingEvent
애플리케이션 실행 시작 시, 리스너와 이니셜라이저가 등록되기 전에 발생합니다. - ApplicationEnvironmentPreparedEvent
컨텍스트에서 사용할 Environment가 결정되었지만, 컨텍스트가 생성되기 전에 발생합니다. - ApplicationContextInitializedEvent
ApplicationContext가 준비되고, ApplicationContextInitializer가 호출된 후, 빈 정의가 로드되기 전에 발생합니다. - ApplicationPreparedEvent
빈 정의가 로드된 후, 리프레시가 시작되기 직전에 발생합니다. - ApplicationStartedEvent
컨텍스트가 리프레시된 후, 애플리케이션 및 커맨드 라인 러너가 호출되기 전에 발생합니다. - AvailabilityChangeEvent (LivenessState.CORRECT)
애플리케이션이 "정상적으로 실행 중(live)" 상태임을 나타내기 위해 LivenessState.CORRECT와 함께 바로 발생합니다. - ApplicationReadyEvent
애플리케이션 및 커맨드 라인 러너가 모두 호출된 후 발생합니다. - AvailabilityChangeEvent (ReadinessState.ACCEPTING_TRAFFIC)
애플리케이션이 요청을 처리할 준비가 되었음을 나타내기 위해 ReadinessState.ACCEPTING_TRAFFIC와 함께 바로 발생합니다. - ApplicationFailedEvent
애플리케이션 시작 중 예외가 발생하면 발생합니다.
위의 목록에는 SpringApplication에 연결된 SpringApplicationEvents만 포함되어 있습니다. 이 외에도 다음과 같은 이벤트도 ApplicationPreparedEvent 이후와 ApplicationStartedEvent 이전에 게시됩니다:
- 웹 서버가 준비된 후에 WebServerInitializedEvent가 전송됩니다. 서블릿 웹 서버 초기화 이벤트와 반응형 웹 서버 초기화 이벤트는 각각 서블릿과 반응형 변형입니다.
- 애플리케이션 컨텍스트가 새로 고쳐질 때 ContextRefreshedEvent가 전송됩니다.
애플리케이션 이벤트를 사용할 필요가 없는 경우가 많지만, 이벤트가 존재한다는 것을 알고 있으면 편리할 수 있습니다. 내부적으로 Spring Boot는 이벤트를 사용하여 다양한 작업을 처리합니다.
이벤트 리스너는 기본적으로 동일한 스레드에서 실행되므로 잠재적으로 긴 작업을 실행해서는 안 됩니다. 대신 애플리케이션 및 명령줄 런너를 사용하는 것을 고려하세요.
애플리케이션 이벤트는 Spring 프레임워크의 이벤트 게시 메커니즘을 사용하여 전송됩니다. 이 메커니즘의 일부는 자식 컨텍스트의 리스너에 게시된 이벤트가 모든 상위 컨텍스트의 리스너에도 게시되도록 합니다. 그 결과, 애플리케이션이 SpringApplication 인스턴스 계층 구조를 사용하는 경우 수신기는 동일한 유형의 애플리케이션 이벤트 인스턴스를 여러 개 수신할 수 있습니다.
수신기가 해당 컨텍스트에 대한 이벤트와 하위 컨텍스트에 대한 이벤트를 구분할 수 있도록 하려면 애플리케이션 컨텍스트가 주입되도록 요청한 다음 주입된 컨텍스트를 이벤트의 컨텍스트와 비교해야 합니다. 컨텍스트는 ApplicationContextAware를 구현하여 주입하거나 수신기가 빈인 경우 @Autowired를 사용하여 주입할 수 있습니다.
Application Enviorment
스프링 애플리케이션은 사용자를 대신하여 올바른 유형의 애플리케이션 컨텍스트를 생성하려고 시도합니다. 웹 애플리케이션 유형을 결정하는 데 사용되는 알고리즘은 다음과 같습니다:
- Spring MVC가 있는 경우, AnnotationConfigServletWebServerApplicationContext가 사용됩니다.
- Spring MVC가 없고 Spring WebFlux가 있는 경우, AnnotationConfigReactiveWebServerApplicationContext가 사용됩니다.
- 그렇지 않으면 AnnotationConfigApplicationContext가 사용됩니다.
즉, 동일한 애플리케이션에서 Spring MVC와 Spring WebFlux의 새로운 WebClient를 사용하는 경우 기본적으로 Spring MVC가 사용됩니다. setWebApplicationType(WebApplicationType)을 호출하여 이를 쉽게 재정의할 수 있습니다.또한 setApplicationContextFactory(...)를 호출하여 사용되는 ApplicationContext 유형을 완전히 제어할 수도 있습니다.
JUnit 테스트 내에서 SpringApplication을 사용할 때는 setWebApplicationType(WebApplicationType.NONE)을 호출하는 것이 바람직할 때가 많습니다.
Accessing Application Arguments
SpringApplication.run(...)에 전달된 애플리케이션 인자에 액세스해야 하는 경우 ApplicationArguments 빈을 주입하면 됩니다. ApplicationArguments 인터페이스는 다음 예제와 같이 구문 분석된 옵션 및 비옵션 인자뿐만 아니라 원시 String[]인자에 대한 액세스를 모두 제공합니다:
@Component
public class MyBean {
public MyBean(ApplicationArguments args) {
boolean debug = args.containsOption("debug");
List<String> files = args.getNonOptionArgs();
if (debug) {
System.out.println(files);
}
// if run with "--debug logfile.txt" prints ["logfile.txt"]
}
}
Spring Boot는 또한 Spring 환경에 CommandLinePropertySource를 등록합니다. 이를 통해 @Value 어노테이션을 사용하여 단일 애플리케이션 인수를 주입할 수도 있습니다.
Using the ApplicationRunner or CommandLineRunner
SpringApplication이 시작된 후 특정 코드를 실행해야 하는 경우 ApplicationRunner 또는 CommandLineRunner 인터페이스를 구현할 수 있습니다. 두 인터페이스 모두 동일한 방식으로 작동하며 SpringApplication.run(...)이 완료되기 직전에 호출되는 단일 실행 메서드를 제공합니다.
이 컨트랙트는 애플리케이션이 시작된 후 트래픽을 수락하기 전에 실행되어야 하는 작업에 적합합니다.
CommandLineRunner 인터페이스는 애플리케이션 인자에 대한 액세스를 문자열 배열로 제공하는 반면, ApplicationRunner는 앞서 설명한 ApplicationArguments 인터페이스를 사용합니다. 다음 예제는 실행 메서드가 있는 CommandLineRunner를 보여줍니다:
@Component
public class MyCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) {
// Do something...
}
}
특정 순서로 호출해야 하는 CommandLineRunner 또는 ApplicationRunner 빈이 여러 개 정의되어 있는 경우 Ordered 인터페이스를 추가로 구현하거나 Order 어노테이션을 사용할 수 있습니다.
Application Exit
각 SpringApplication은 종료 시 ApplicationContext가 정상적으로 닫히도록 하기 위해 JVM에 종료 훅을 등록합니다. 모든 표준 Spring 라이프사이클 콜백(예: DisposableBean 인터페이스 또는 @PreDestroy 어노테이션)을 사용할 수 있습니다.
또한, SpringApplication.exit()가 호출될 때 특정 종료 코드를 반환하려는 경우 빈은 ExitCodeGenerator 인터페이스를 구현할 수 있습니다. 그런 다음 다음 예제와 같이 이 종료 코드를 System.exit()에 전달하여 상태 코드로 반환할 수 있습니다:
@SpringBootApplication
public class MyApplication {
@Bean
public ExitCodeGenerator exitCodeGenerator() {
return () -> 42;
}
public static void main(String[] args) {
System.exit(SpringApplication.exit(SpringApplication.run(MyApplication.class, args)));
}
}
또한 ExitCodeGenerator 인터페이스는 예외로 구현될 수 있습니다. 이러한 예외가 발생하면 Spring Boot는 구현된 getExitCode() 메서드에서 제공한 종료 코드를 반환합니다.
ExitCodeGenerator가 두 개 이상인 경우 생성된 첫 번째 0이 아닌 종료 코드가 사용됩니다. 생성기가 호출되는 순서를 제어하려면 Ordered 인터페이스를 추가로 구현하거나 Order 어노테이션을 사용합니다.
Admin feature
spring.application.admin.enabled 속성을 지정하여 애플리케이션의 관리자 관련 기능을 활성화할 수 있습니다. 이렇게 하면 플랫폼 MBeanServer에 SpringApplicationAdminMXBean이 노출됩니다. 이 기능을 사용하여 Spring Boot 애플리케이션을 원격으로 관리할 수 있습니다. 이 기능은 모든 서비스 래퍼 구현에도 유용할 수 있습니다.
애플리케이션이 어떤 HTTP 포트에서 실행되고 있는지 알고 싶다면 local.server.port 키로 속성을 가져옵니다.
Application Startup tracking
애플리케이션이 시작되는 동안 SpringApplication과 ApplicationContext는 애플리케이션 수명 주기, 빈 수명 주기 또는 애플리케이션 이벤트 처리와 관련된 많은 작업을 수행합니다. Spring 프레임워크는 ApplicationStartup을 통해 StartupStep 객체를 사용하여 애플리케이션 시작 시퀀스를 추적할 수 있습니다. 이 데이터는 프로파일링 목적으로 수집하거나 애플리케이션 시작 프로세스를 더 잘 이해하기 위해 수집할 수 있습니다.
SpringApplication 인스턴스를 설정할 때 ApplicationStartup 구현을 선택할 수 있습니다. 예를 들어 버퍼링 애플리케이션 시작을 사용하려면 다음과 같이 작성할 수 있습니다:
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(MyApplication.class);
application.setApplicationStartup(new BufferingApplicationStartup(2048));
application.run(args);
}
}
사용 가능한 첫 번째 구현인 FlightRecorderApplicationStartup은 Spring 프레임워크에서 제공합니다.
이는 Java Flight Recorder 세션에 Spring 관련 시작 이벤트를 추가하며 애플리케이션을 프로파일링하고 애플리케이션의 Spring 컨텍스트 라이프사이클을 JVM 이벤트(예: 할당, GC, 클래스 로딩...)와 상호 연관시키기 위한 것입니다.구성이 완료되면 플라이트 레코더를 활성화한 상태에서 애플리케이션을 실행하여 데이터를 기록할 수 있습니다:
$ java -XX:StartFlightRecording:filename=recording.jfr,duration=10s -jar demo.jar
이 구현은 시작 단계를 버퍼링하고 외부 메트릭 시스템으로 배출하기 위한 것으로, Spring Boot에는 BufferingApplicationStartup 변형이 함께 제공됩니다.
애플리케이션은 모든 컴포넌트에서 BufferingApplicationStartup 유형의 빈을 요청할 수 있습니다.
또한 이 정보를 JSON 문서로 제공하는 시작 엔드포인트를 노출하도록 Spring Boot를 구성할 수도 있습니다.
Virtual threads
애플리케이션에 이 옵션을 켜기 전에 공식 Java 가상 스레드 설명서를 읽어보시기 바랍니다. 경우에 따라 애플리케이션에서 '고정된 가상 스레드'로 인해 처리량이 저하될 수 있으며, 이 페이지에서는 JDK Flight Recorder 또는 jcmd CLI로 이러한 경우를 감지하는 방법도 설명합니다.
tip가상 스레드의 한 가지 부작용은 가상 스레드가 데몬 스레드라는 점입니다. 모든 스레드가 데몬 스레드인 경우 JVM이 종료됩니다. 이 동작은 예를 들어 애플리케이션을 계속 유지하기 위해 @Scheduled 빈에 의존하는 경우 문제가 될 수 있습니다. 가상 스레드를 사용하는 경우 스케줄러 스레드는 가상 스레드이므로 데몬 스레드이므로 JVM을 계속 유지하지 않습니다. 이는 스케줄링에만 영향을 미치는 것이 아니라 다른 기술에서도 마찬가지입니다. 모든 경우에 JVM을 계속 실행하려면 spring.main.keep-alive 속성을 true로 설정하는 것이 좋습니다. 이렇게 하면 모든 스레드가 가상 스레드인 경우에도 JVM이 계속 활성화됩니다.
가상 스레드가 활성화된 경우 스레드 풀을 구성하는 속성은 더 이상 영향을 미치지 않습니다. 가상 스레드는 전용 스레드 풀이 아닌 JVM 전체 플랫폼 스레드 풀에서 예약되기 때문입니다.
warnings
게시물은 SpringBoot 문서를 읽고 공부하기 위해서 작성했습니다. 번역은 DeepL + GPT4o를 활용해서 진행했습니다.
'Java > Spring, SpringBoot' 카테고리의 다른 글
[SpringBoot] 폴더링에 관련해서 (설 맞이 해커톤 1일차) (0) | 2025.01.29 |
---|---|
[Spring] Spring IoC 컨테이너와 빈에 대한 소개 (day2) (0) | 2025.01.24 |
[SpringBoot] JDBC를 통해 SQL 실행하기(JDBC Connection과 Memory Exceed) (0) | 2025.01.23 |