Spring Bean의 생명주기

서버란·2024년 11월 4일

스프링

목록 보기
1/4

Spring Bean의 생명주기는 Spring 프레임워크에서 Bean 객체의 생성과 소멸을 관리하는 중요한 개념입니다. 이 생명주기는 Bean의 스코프에 따라 달라지며, 각각의 스코프는 Bean이 언제 생성되고, 언제 소멸되는지를 정의합니다. 아래는 주요 생명주기와 스코프에 대한 설명입니다.

1. Bean Scope (스코프)

Spring은 다양한 Bean 스코프를 제공하며, 이를 통해 Bean이 생성되고 소멸되는 시점을 결정할 수 있습니다. 주요 스코프는 아래와 같습니다.

1.1 Singleton (기본값)

  • 특징: 애플리케이션 전역에서 하나의 인스턴스만을 유지합니다.
  • 생명주기: ApplicationContext가 시작될 때 초기화되고, ApplicationContext가 종료될 때 소멸됩니다.
  • 장점: 메모리 효율적이며 애플리케이션 전체에서 동일한 인스턴스를 사용함으로써 공유 자원으로 활용 가능합니다.

1.2 Prototype

  • 특징: 요청될 때마다 새로운 인스턴스를 생성합니다.
  • 생명주기: Bean이 생성될 때만 Spring 컨테이너가 관리하고, 이후에는 호출자가 직접 관리해야 합니다.
  • 소멸: Spring 컨테이너가 소멸을 관리하지 않으므로, 더 이상 참조되지 않을 때 가비지 컬렉터(GC)에 의해 제거됩니다.

1.3 Request (웹 애플리케이션 전용)

  • 특징: HTTP 요청 하나가 들어오고 나갈 때까지 유지되는 스코프입니다.
  • 생명주기: 각 HTTP 요청마다 새로운 인스턴스가 생성되며, 요청이 종료되면 소멸됩니다.

1.4 Session (웹 애플리케이션 전용)

  • 특징: HTTP 세션과 동일한 생명주기를 가지는 스코프입니다.
  • 생명주기: 각 세션마다 새로운 인스턴스가 생성되며, 세션이 종료되면 소멸됩니다.

1.5 Application (웹 애플리케이션 전용)

  • 특징: ServletContext와 동일한 생명주기를 가지는 스코프입니다.
  • 생명주기: 애플리케이션 전체에서 하나의 인스턴스가 유지되며, ServletContext가 종료될 때 함께 소멸됩니다.

1.6 WebSocket (웹 애플리케이션 전용)

  • 특징: 웹소켓과 동일한 생명주기를 가지는 스코프입니다.
  • 생명주기: 웹소켓 연결이 유지되는 동안 인스턴스가 유지되며, 연결이 종료될 때 소멸됩니다.

2. Singleton vs Prototype

2.1 Singleton

  • 의미: singleton 스코프는 애플리케이션 전역에서 하나의 인스턴스를 공유하는 패턴입니다.
  • 생성 시점: ApplicationContext 시작 시에 초기화됩니다.
  • 소멸 시점: ApplicationContext 종료 시에 소멸됩니다.

2.2 Prototype

  • 의미: prototype 스코프는 요청마다 새로운 인스턴스를 생성하며, 생성된 Bean은 호출자가 직접 관리해야 합니다.
  • 생성 시점: 객체가 요청될 때마다 새로운 인스턴스가 생성됩니다.
  • 소멸 시점: 더 이상 참조되지 않아서 GC의 대상이 될 때까지 유지됩니다.
  • 추가 사항: Bean 생명주기 메서드

Spring은 Bean의 생명주기를 관리하기 위해 초기화 및 소멸 메서드를 지원합니다. @PostConstruct와 @PreDestroy를 사용하여 Bean이 생성되거나 소멸될 때 특정 동작을 수행할 수 있습니다.

  • @PostConstruct: Bean이 생성된 후 의존성 주입이 완료되었을 때 호출되는 초기화 메서드를 정의합니다.
  • @PreDestroy: Bean이 소멸되기 직전에 호출되는 메서드를 정의하여, 자원 해제 등 필요한 작업을 수행할 수 있습니다.

이 메서드를 통해 Bean이 생성되고 소멸되는 시점에 특정 로직을 실행하여 보다 안정적이고 효율적인 자원 관리를 구현할 수 있습니다.

Custom Bean 생명주기 메서드 설정

Spring에서는 XML 설정 파일이나 Java Config 파일을 통해 직접 초기화와 소멸 메서드를 설정할 수도 있습니다.

  • XML 설정: 태그에서 init-method와 destroy-method 속성을 지정하여 초기화 및 소멸 메서드를 설정할 수 있습니다.
  • Java Config: @Bean(initMethod="init", destroyMethod="destroy")와 같은 어노테이션을 통해 직접 초기화와 소멸 메서드를 지정할 수 있습니다.

이러한 생명주기 메서드는 특정 객체가 의존하는 자원이나 네트워크 연결을 생성하고 종료하는 데 유용하며, Spring이 제공하는 유연한 설정 옵션을 통해 보다 유연한 Bean 관리가 가능합니다.


Q1: 프로토타입 스코프를 사용할 때 주의해야 할 점은 무엇이 있을까요?

  • 메모리 관리: 프로토타입 스코프의 Bean은 요청마다 새로운 인스턴스가 생성되므로, 관리되지 않는 Bean이 많이 생성될 경우 메모리 사용량이 급격히 증가할 수 있습니다. 따라서 필요할 때만 인스턴스를 생성하고, 사용 후에는 참조를 끊어 가비지 컬렉터에 의해 회수될 수 있도록 관리해야 합니다.

  • 의존성 주입 관리: 프로토타입 스코프 Bean은 소멸 관리를 Spring이 하지 않기 때문에, 외부 리소스나 네트워크 연결을 사용하는 경우 명시적으로 종료하는 코드가 필요합니다.

  • 싱글톤 Bean과의 조합: 싱글톤 Bean이 프로토타입 Bean을 참조할 때, 매번 새로운 프로토타입 인스턴스를 주입받으려면 @Scope("prototype")과 @Lookup 메서드 또는 ObjectFactory 같은 방식으로 매번 새 인스턴스를 생성하도록 구성해야 합니다.

Q2: 웹 애플리케이션에서 다양한 스코프의 Bean을 사용할 때 메모리 관리에 있어 주의할 점은 무엇인가요?

  • Request 및 Session 스코프 Bean 관리: HTTP 요청(Request) 스코프와 세션(Session) 스코프 Bean은 웹 요청이나 세션이 종료되면 자동으로 소멸되지만, 필요 이상으로 많은 인스턴스를 생성하게 되면 서버 메모리에 부담이 될 수 있습니다. 따라서, 세션 스코프 Bean은 세션 만료 정책을 잘 설정하고, 필요한 데이터만 유지해야 합니다.

  • Application 스코프의 적절한 사용: 애플리케이션 스코프의 Bean은 애플리케이션 전체에서 공유되므로 싱글톤처럼 활용할 수 있습니다. 단, 이 Bean은 서버가 종료될 때까지 메모리를 점유하므로, 메모리를 과도하게 사용하거나 불필요한 인스턴스를 유지하지 않도록 주의가 필요합니다.

  • WebSocket 스코프 Bean 관리: 웹소켓 스코프 Bean은 웹소켓 연결이 유지되는 동안 계속 인스턴스를 유지합니다. 지속적인 연결이 유지되는 환경에서 필요 이상으로 큰 데이터를 가지고 있다면 서버 메모리 문제를 일으킬 수 있으므로, 데이터 크기 및 수명 주기를 신중하게 관리하는 것이 좋습니다.

Q3: @PostConstruct와 @PreDestroy를 활용하여 Bean의 초기화와 소멸 시 실행할 로직을 설정하는 경우, 대표적인 사용 사례에는 어떤 것들이 있나요?

@PostConstruct 사용 사례:

  • 리소스 초기화: 데이터베이스 연결이나 파일 리더 객체 등 리소스를 초기화할 때 유용합니다.
  • 캐싱 데이터 초기화: Bean 생성 시에 외부 API나 DB에서 데이터를 가져와 캐싱할 필요가 있을 때 사용합니다.
  • 기본 설정 값 로드: 애플리케이션 시작 시, 특정 설정 값을 외부 파일이나 환경 변수에서 로드하여 Bean에 설정할 때 유용합니다.

@PreDestroy 사용 사례:

  • 리소스 해제: 데이터베이스 연결, 파일 핸들러 등의 리소스를 명시적으로 해제해야 할 경우 사용합니다.
  • 임시 파일 삭제: 애플리케이션 실행 중 생성한 임시 파일을 소멸 시점에 정리할 때 활용할 수 있습니다.
  • 로그 기록: 애플리케이션 종료 전 특정 로그를 남기거나 사용 기록을 파일에 저장할 때 유용하게 사용됩니다.

이 두 어노테이션을 통해 초기화 및 종료 시 필요한 작업을 Bean 내부에서 직접 관리할 수 있어 코드의 가독성과 유지보수성이 높아집니다.

profile
백엔드에서 서버엔지니어가 된 사람

0개의 댓글