cs

라이프 사이클 (LifeCycle)에 대한 이해

sihanni 2025. 6. 23. 11:25

라이프 사이클 (LifeCycle) 을 알아야 하는 이유

라이프사이클은 어떤 객체나 시스템이 생성되고, 동작하다가 종료되기까지의 흐름을 의미한다.

라이프사이클을 이해하고 있으면, 애플리케이션이 어떤 순서로 동작하는지를 알 수 있기 때문에 로직을 어디에 넣어야 할지를 정확하게 판단할 수 있다.

또한 특정 기술의 동작 원리를 이해할 때도 라이프사이클에 대한 파악이 중요하다.

이 흐름을 이해하면 디버깅, 최적화, 확장 등의 관점에서 유리하고 안정적인 코드 작성이 가능하다.

라이프사이클의 기본 구조

라이프사이클은 일반적으로 다음과 같은 흐름을 가진다.

  • 생성 (Initialization): 객체 또는 애플리케이션이 메모리에 할당되고 초기화되는 시점
  • 사용 (Execution): 로직이 실행되고 이벤트가 처리되는 시점
  • 종료 (Destruction/Termination): 리소스가 정리되고 객체가 메모리에서 해제되는 시점

Node.js의 라이프사이클

Node.js는 자바스크립트의 런타임 환경이며, 이벤트 기반 비동기 구조를 가지고 있다.

  1. 애플리케이션 시작: node app.js로 실행
  2. 모듈 로딩 및 초기화: require, 환경설정 등
  3. 이벤트 루프 실행: 비동기 작업 큐 등록 및 처리 (I/O, 타이머 등)
  4. 종료 처리: SIGINT, SIGTERM, process.exit() 등으로 프로세스 종료

Express의 라이프사이클

Express는 Node.js 기반의 웹 프레임워크로, HTTP 요청(Request) 단위로 라이프사이클을 가진다.

하나의 HTTP 요청이 들어오면 다음과 같은 과정을 거치게 된다.

  1. 요청 수신
  2. 미들웨어 실행: app.use(...) 또는 router.use(...)
  3. 라우팅 처리: app.get(...), app.post(...) 등
  4. 핸들러 로직 처리: 서비스 로직, DB 호출 등
  5. 응답 반환: res.send(...), res.json(...)
  6. 요청 종료

Express의 핵심은 **미들웨어 체인(next)**을 따라 요청을 처리한다는 점이며, 이 체인을 통해 인증, 로깅, 에러 처리 등을 유연하게 삽입할 수 있다. (ex. router에서 커스텀인증을 app.get뒤에 추가 삽입한다던지)

NestJS의 라이프사이클

NestJS는 Angular에서 영감을 받은 Node.js 기반 프레임워크로, 의존성 주입(DI)과 객체지향 구조를 중심으로 동작한다.

NestJS에서는 애플리케이션 전체, 요청 처리, 컴포넌트 단위로 각각 라이프사이클을 정의할 수 있다.

 

  • 애플리케이션 라이프 사이클
    1. main.ts 에서 NestFactory.create() 호출
    2. 루트 모듈 (AppModule) 초기화
    3. DI 컨테이너가 모든 provider/controller 인스턴스화
    4. 앱 부트스트랩 및 실행 (app.listen())
  • 요청 라이프사이클
    • NestJS는 기본적으로 Express위에서 동작하며, 다음과 같은 구조를 가진다.
      • Guard: 요청 차단 또는 허용
      • Pipe: 요청 데이터 변환 및 유효성 검사
      • Interceptor: 요청 전후 로직 삽입 (로깅, 캐싱 등)
      • Controller: 요청 처리 진입점
      • Service: 실제 비즈니스 로직 처리
      • 응답 반환
  • 컴포넌트(provider) 레벨 라이프사이클 hook
    • NestJS는 특정 라이프사이클 지점에서 Hook을 제공한다.
    • @Injectable, @Controller 등이 Nest에 의해 생성될 때 실행되는 Hook들
@Injectable()
export class MyService implements OnModuleInit, OnModuleDestroy {
  onModuleInit() {
    console.log('초기화 로직');
  }

  onModuleDestroy() {
    console.log('종료 로직');
  }
}

// OnModuleInit :모듈이 초기화된 후 실행
// OnApplicationBootstrap : 애플리케이션 전체 초기화 후 실행
// OnModuleDestroy : 모듈이 종료되기 직전 실행
// OnApplicationShutdown : 애플리케이션 종료 직전 실행

 

 

기본적으로 Nest는 싱글톤이므로 대부분의 Provider은 앱 시작 시 한번만 생성된다.

하지만 요청마다 인스턴스를 새로 생성하는 경우에는 요청마다 컴포넌트가 새로 생성되기 때문에 요청 레벨과 컴포넌트 레벨이 겹치게 된다.

{ provide: SomeService, scope: Scope.REQUEST }

정리하면 NestJS 컴포넌트는 기본적으로 싱글톤이기 때문에 애플리케이션 전체 라이프사이클과 함께 생성되고 종료된다.

그리고 요청 라이프사이클은 요청마다 독립적으로 실행된다.

 

비교

항목 Node.js Express NestJS
기준 애플리케이션 HTTP 요청 애플리케이션 + 요청 + 컴포넌트
구조 이벤트 루프 중심 미들웨어 체인 중심 DI, 모듈, 데코레이터 중심 구조
Hook/처리 포인트 process.on() app.use(), next() Guard, Pipe, Interceptor, Hook 인터페이스 등
핵심 이벤트 루프 요청-응답 미들웨어 체인 모듈/프로바이더 초기화 + 훅 기반 실행 흐름

 

정리

라이프사이클은 단순한 이론이 아니라, 실무에서 코드를 언제, 어디에 배치해야 하는지를 판단하는 기준이 된다.
평소엔 당연하게 여겼던 흐름도 이렇게 구조적으로 정리해보니, 각 기술의 특성과 내부 동작을 더 깊이 이해할 수 있었고,
앞으로 더 안정적이고 유지보수하기 좋은 코드를 작성하는 데 큰 도움이 될 것 같다.

'cs' 카테고리의 다른 글

[cs] 2. 네트워크 (기초)  (0) 2025.07.12
Proxy (Reverse Proxy / Forward Proxy)  (0) 2025.06.23
[기억 장치] 디스크와 메모리  (0) 2025.06.08
[WEB] REST, RESTful API  (1) 2025.06.04
HTTP와 HTTPS 란?  (0) 2025.01.28