1. SpringApplication
- SpringApplication 클래스는 Spring application을 편리하게 기동하는 방법을 제공하는 클래스입니다.
- SpringApplication.run 메서드가 main method로부터 호출되어 bootstrapping 작업을 시작합니다.
- 기본적으로 INFO 레벨의 로그가 찍이도록 설정됩니다.
- startup과 연관된 메시지가 출력됩니다.
Startup Failure
- FaliureAnalyzers는 Spring Boot 기동중 에러 발생 시 문제 해결을 담당합니다.
- 여러 구현체를 가지고 있습니다.
- 에러 메시지를 출력합니다.
- 에러를 처리할 수 없다면, 원인 파악을 위해 DEBUG 레벨의 로그를 확인해야 합니다.
- DEBUG 레벨 로그는 Full Conditions Report를 제공합니다.
- DEBUG 로그 레벨 설정방법
- environment에 debug 속성 주기
- java argument에 --debug 추가
- Condition Evaluation Report의 속성값을 debug로 주기
- ConditionEvaluationReport: 어떤 auto-configuration이 활성화되었는지 확인하는 기능
Lazy Initialization
- SpringApplication 클래스는 지연 초기화 기능을 지원합니다.
- 지연 초기화는 빈들이 애플리케이션이 시작될 때 초기화 되는것이 아닌 필요로 하는 시점에 객체가 초기화되는 기능입니다.
- 장점
- 애플리케이션이 기동되는 시간을 줄여줍니다.
- 빈들은 필요로 할때 (HTTP Request로 인한 필요) 초기화됩니다.
- 단점
- 객체 생성 코드에 대한 문제를 늦게 발견합니다.
- 잘못 셋팅된 빈이 지연 초기화 된다면 기동시에 문제점이 발견되지 않고 필요에 의해 초기화될 때 발견됩니다.
- 필요한 시점에 초기화되므로 메모리 용량이 모든 빈의 생성을 수용할 수 있어야 합니다.
- 런타임에 메모리 부족으로 인해 서버가 죽을 수 있습니다.
- 이를 고려하여 서버 기동 전 JVM의 Heap 사이즈가 충분하게 할당되어야 합니다.
- 객체 생성 코드에 대한 문제를 늦게 발견합니다.
- 지연 초기화 활성화 방법
- SpringApplicationBuilder의 lazyInitialization() 을 통한 SpringApplication 생성
- SpringApplication의 setLazyInitialization() 호출
- spring.main.lazy-initialization 속성 사용
- @Lazy 어노테이션 사용 (특정 빈에서만 지연 초기화 설정)
Application Availability
- 관리 플랫폼에서 애플리케이션이 배포될 경우, Spring Application은 플랫폼에게 availability 정보를 제공해야 합니다
- Spring Boot는 health endpoint를 제공하는 actuator 모듈을 지원합니다.
- actuator 모듈은 두가지 availability 정보를 제공합니다 (liveness, readiness)
1. Liveness State
- 정상 Liveness State는 애플리케이션이 내부에서 '정상 동작' 중이거나 '에러를 스스로 회복할 수 있는 상태'를 의미합니다.
- 손상 Liveness State는 '에러를 스스로 회복할 수 없는 상태'를 뜻합니다.
- Liveness State는 외부 시스템의 상태를 기반해서 결정되면 안됩니다.
- Spring Application의 상태가 정상이더라도 외부 시스템이 에러 상황인 경우 손상 Liveness State로 판명됩니다.
- 이러한 경우 Spring Application에서 의존하는 외부 시스템 전체를 연쇄적으로 재실행 시켜야 할 수 있습니다.
- Spring Application의 상태는 ApplicationContext 기반으로 표현되어야 합니다.
- 보통 ApplicationContext가 리프레쉬 후에 Spring Application의 상태는 정상이라 간주됩니다.
2. Readiness State
- 정상 Readiness State는 애플리케이션이 정상적으로 트래픽을 처리할 수 있는 상태를 의미합니다.
- 손상 Readiness State는 애플리케이션이 정상적으로 트래픽을 처리할 수 없는 상태를 의미합니다.
- 애플리케이션에 트래픽이 몰릴때의 상태입니다.
- 보통 애플리케이션이 실행중 상태입니다.
- CommandLineRunner 혹은 ApplicationRunner가 실행중인 상황입니다.
- Spring Component 라이프사이클의 콜백인 @PostConstruct를 뜻하지 않습니다.
3. Managing the Application Availability State
- ApplicationAvailability를 사용하면 현재 애플리케이션의 가용성 상태를 조회할 수 있습니다.
Application Events and Listeners
- SpringApplication 클래스는 애플리케이션의 시작 프로세스를 관리합니다
- 이벤트 드리븐 매커니즘으로 초기화 작업을 수행합니다.
- 애플리케이션 기동시 ApplicationEvent를 발행합니다.
- 몇몇의 ApplicationEvent는 ApplicationContext 초기화 전의 이벤트를 가집니다.
- ApplicationListener는 이러한 ApplicationEvent를 listen하는데 쓰입니다.
- META-INF/spring.factories 파일에 작성하여 등록하기
- environment에 org.springframework.context.ApplicationListener을 key로 한 구현체를 등록하기
- SpringApplication 클래스로 ApplicationListener 등록하기
ApplicationEvent 발행순서
- ApplicationStartingEvent
애플리케이션이 시작될 때 발생합니다. (Listener와 Initializer의 등록만 이루어진 상태) - ApplicationEnvironmentPreparedEvent
사용될 Environment가 알려져 있지만, 아직 ApplicationContext가 생성되기 전의 상태입니다. - ApplicationContextInitializedEvent
ApplicationContext가 준비되고 ApplicationContextInitializers가 호출되었으나 빈 정의가 로드되기 전의 상태입니다. - ApplicationPreparedEvent
빈 정의들이 로드된 후, refresh가 시작되기 전에 발생합니다.
(refresh를 시도하며 WebServer를 초기화합니다)
4-1. WebServerInitializedEvent : WebServer가 초기화 된 후 발생합니다.
4-2. ContextRefreshedEvent : Bean이 모두 초기화되어 ApplicationContext가 refresh 될 때 발생합니다. - ApplicationStartedEvent
ApplicationContext가 refresh 된 후, ApplicationRunner 혹은 CommandLineRunner가 호출되기 전에 발생합니다. - ApplicationChangeEvent (LivenessState.CORRECT)
애플리케이션이 정상적으로 실행중임을 나타낼 때 발생합니다. - ApplicationReadyEvent
ApplicationRunner 혹은 CommandLineRunner가 호출된 후 발생합니다. - AvailabilityChangeEvent (ReadinessState.ACCEPTING_TRAFFIC)
애플리케이션이 서비스 요청을 처리할 준비가 되었음을 나타내기 위해 발생합니다 - ApplicationFailedEvent
애플리케이션의 시작 중에 예외가 발생하면 트리거됩니다.
- ApplicationEvent는 Spring Framework의 이벤트 발행 매커니즘을 통해 발행됩니다.
- 발행된 ApplicationEvent는 등록된 Listener들에게 전달됩니다.
- ApplicationContext는 계층 구조를 가지며
- 자식 ApplicationContext에서 ApplicationEvent 발행하면 부모 ApplicationContext에 ApplicationEvent가 전파됩니다.
- ApplicationContext의 Listener는 전달받은 ApplicationEvent가 자신이 발행한건지 전파된건지 구분해야 합니다.
- 이를 위해 Listener는 자신이 속한 ApplicationContext의 참조를 가지고 있어야 합니다.
- Listener는 ApplicationContextAware 인터페이스를 구현함으로써 자신의 ApplicationContext 참조 가질 수 있습니다
- Listener가 빈으로 등록되어 있다면 @Autowired로 ApplicationContext를 주입받을 수 있습니다.
Web Environment
- SpringApplication은 현재 애플리케이션에 적절한 ApplicationContext 타입인 WebApplicationType을 정해줍니다.
- Spring MVC 를 사용한다면 AnnotationConfigServletWebServerApplicationContext 타입을 사용합니다.
- Spring MVC, Spring WebFlux 동시에 사용한다면 AnnotationConfigServletWebServerApplicationContext
- Spring WebFlux를 사용한다면 AnnotationConfigReactiveWebServerApplicationContext 타입을 사용합니다.
- 다른 경우라면 AnnotationConfigApplicationContext 타입을 사용합니다.
- SpringApplication은 setWebApplicationType()을 호출하여 명시적으로 지정할 수 있습니다.
Accessing Application Arguments
- Spring Boot 실행 시, 명령행의 인자는 ApplicationArguments 타입의 빈으로 등록됩니다.
- Environment는 CommandLinePropertySource를 의존성으로 등록합니다.
- 이로 인해 @Value 어노테이션으로 프로퍼티 값을 주입받을 수 있습니다.
Using the ApplicationRunner or CommandLineRunner
- Spring Boot 실행 시 코드를 실행시키고 싶다면 ApplicationRunner 혹은 CommandLineRunner를 사용하면 된다.
- ApplicationContext의 빈 초기화가 끝난 후 ApplicationRunner 혹은 CommandLineRunner 코드가 실행된다
- 순서를 정의하고 싶을 경우, Ordered 인터페이스나 @Order 를 붙여 선언하면 된다.
- ApplicationRunner는 명령행의 인자를 ApplicationArguments 빈으로 주입받을 수 있다.
- CommandLineRunner는 run 함수의 파라미터로 String 배열을 주입받을 수 있다
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@Component
public class MyCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) {
// Do something...
}
}
참고
'Spring > Spring Boot' 카테고리의 다른 글
[Spring Boot] 2-3. Core Features: Profile (0) | 2023.10.09 |
---|---|
[Spring Boot] 2-2. Core Features: Externalized Configuration (2) | 2023.10.09 |
[Spring Boot] 1-2. Spring Boot 사용하기 (1) | 2023.10.07 |
[Spring Boot] 1-1. Spring Boot 사용하기 (0) | 2023.10.07 |
[Spring Boot][KoLiving] 3-2 Sign-up (0) | 2023.09.19 |