67 lines
4.9 KiB
Markdown
67 lines
4.9 KiB
Markdown
---
|
|
title: concept / Spring SmartLifecycle
|
|
source_type: llm-generated
|
|
status: reviewed
|
|
confidence: high
|
|
tags: [concept, ca-tmpl, runtime, spring-framework, graceful-shutdown]
|
|
related_projects: [ca-tmpl]
|
|
last_reviewed: 2026-06-15
|
|
---
|
|
|
|
# concept / Spring SmartLifecycle
|
|
|
|
## Summary
|
|
|
|
Spring 컨텍스트의 생명 주기(start / stop)에 통합되어, 빈의 시작 및 종료 순서를 결정론적으로(Deterministic) 제어할 수 있게 해주는 인터페이스.
|
|
- 애플리케이션 종료 시점에 리소스 반납 및 진행 중인 트랜잭션/재시도의 중단을 순서대로 조율하여 우아한 종료(Graceful Shutdown)를 돕는다.
|
|
|
|
## Standard (공식 정의)
|
|
|
|
Spring Framework 공식 명세에 따른 정의는 다음과 같다.
|
|
- **SmartLifecycle**: `Lifecycle` 및 `Phased` 인터페이스의 확장판.
|
|
- **isAutoStartup()**: 컨텍스트 리프레시 시점에 `start()`가 자동으로 실행될지 여부를 결정한다.
|
|
- **getPhase()**: 생명 주기 상의 실행 단계를 나타낸다.
|
|
- **시작(Start) 순서**: `getPhase()`가 **작은 순**에서 **큰 순**으로 기동된다.
|
|
- **종료(Stop) 순서**: `getPhase()`가 **큰 순**에서 **작은 순**(내림차순)으로 정지된다.
|
|
- 따라서, phase가 `Integer.MAX_VALUE`인 빈은 가장 마지막에 기동되고, **종료 시점에는 가장 먼저** 멈춘다.
|
|
|
|
## 한계 / 주의점
|
|
|
|
- **ContextClosedEvent 와의 차이**: Spring의 `ContextClosedEvent` 리스너는 애플리케이션 컨텍스트가 닫히기 시작했다는 신호만 전달할 뿐, 빈의 소멸(destroy) 순서와 비결정론적으로 얽혀 있다. 예컨대 어떤 DB 소스 빈이 이미 소멸된 후에 커넥션을 수립하려는 리스너 코드가 호출되면 NPE나 의존성 부재 예외가 터진다.
|
|
- **SmartLifecycle은 비동기 셧다운을 차단할 수 있다**: `stop(Runnable callback)` 메서드가 호출되면 종료 작업을 수행하고 반드시 callback을 호출해 주어야 한다. 그렇지 않으면 Spring이 설정된 셧다운 타임아웃까지 대기하여 기동 종료 과정이 지연될 수 있다.
|
|
|
|
## Project Application
|
|
|
|
- [[wiki/explainer/adapter-outbound.md]]
|
|
- `OutboundHttpShutdownGuard`가 `SmartLifecycle`을 구현하고 `getPhase()`에서 `Integer.MAX_VALUE`를 반환함.
|
|
- 이로 인해 Spring 컨텍스트가 종료 과정을 개시할 때, 다른 어떤 데이터베이스 빈이나 아웃바운드 의존성 어댑터가 종료되기 전에 **가장 먼저** 셧다운 가드의 `stop()`이 실행되어 `shuttingDown` 플래그를 세우게 됨.
|
|
- 리트라이 정책(`OutboundRetryPolicy`)은 루프 도중 이 플래그를 관찰하여 즉시 중단(short-circuit)하며, 신규 요청 또한 `OutboundHttpClient` 단에서 즉시 거부(`DEPENDENCY_CIRCUIT_OPEN` 예외)함으로써, 애플리케이션 종료 시 불필요한 HTTP 커넥션 맺기나 타임아웃 예산 낭비를 미연에 방지함.
|
|
|
|
## Claim-backed Knowledge
|
|
|
|
| Knowledge Point | Supporting Claims | Confidence | Notes |
|
|
|---|---|---|---|
|
|
| Spring SmartLifecycle 생명 주기 제어 및 phase 결정 규칙 | `raw/official-docs/spring-smartlifecycle-reference.md` | `high` | Spring Framework 공식 참조 |
|
|
| Spring Boot Graceful Shutdown 시그널 수신 및 정리 과정 | `raw/official-docs/spring-boot-graceful-shutdown-reference.md` | `high` | Spring Boot Reference Guide |
|
|
|
|
## 내가 설명할 수 있어야 하는 것
|
|
|
|
- `Lifecycle`과 `SmartLifecycle` 인터페이스의 근본적인 차이는 무엇인가?
|
|
- 왜 Graceful Shutdown 구현 시 `ContextClosedEvent` 리스너를 사용하는 대신 `SmartLifecycle` phase를 활용하는 것이 안전한가?
|
|
- `getPhase()` 반환값이 `Integer.MAX_VALUE`일 때, 종료 시점의 제어 순서는 어떻게 보장되는가?
|
|
|
|
## Interview Questions
|
|
|
|
- Spring Framework에서 애플리케이션이 안전하게 종료(Graceful Shutdown)되도록 빈의 소멸 순서를 조율하는 방법에 대해 설명하고, `SmartLifecycle` 인터페이스의 동작 방식을 설명하십시오.
|
|
- Kubernetes 환경에서 Pod가 종료 신호(SIGTERM)를 받았을 때 Spring Boot 애플리케이션이 수신 중인 API 및 아웃바운드 재시도 요청을 처리하는 우아한 종료 흐름을 설계해 보십시오.
|
|
|
|
## Do Not Overclaim
|
|
|
|
- "SmartLifecycle을 적용했기 때문에 종료 과정에서 어떠한 데이터 유실도 물리적으로 발생하지 않는다"고 보장해서는 안 된다. 컨테이너 셧다운 유예 기간(Kubernetes `terminationGracePeriodSeconds`)을 넘어가면 강제 종료(SIGKILL)가 발생하므로, 애플리케이션의 우아한 정리 시간이 유예 기간보다 짧도록 세심히 설정해야만 보장된다.
|
|
|
|
## Sources
|
|
|
|
- [Spring Framework Reference - SmartLifecycle](https://docs.spring.org/spring-framework/reference/core/beans/factory-nature.html#beans-factory-lifecycle)
|
|
- [[raw/official-docs/spring-smartlifecycle-reference.md]]
|
|
- [[raw/official-docs/spring-boot-graceful-shutdown-reference.md]]
|