Bean 생명주기 관리

parkrootseok·2025년 1월 27일

스프링

목록 보기
2/12
post-thumbnail

Bean 생명주기 관리란?

Bean이란?

Bean은 IoC 컨테이너에 의해 관리되고 있는 재사용 가능한 객체를 의미합니다.

Bean 생명주기 관리는 IoC 컨테이너의 주요 기능으로 생성 -> Bean의 등록, 생성(의존성 주입), 초기화, 사용, 소멸 과정을 관리하는 것을 의미합니다. 이 과정을 통해 객체 간의 관계를 자동으로 설정할 수 있습니다.

Bean 등록

Bean 등록은 Bean을 정의하고 이를 기반으로 BeanDefinition 객체로 변환하여, IoC 컨테이너에 생성할 Bean에 대한 정보를 알리는 과정을 말합니다. 이 과정을 통해, IoC 컨테이너는 어떤 클래스를 Bean으로 생성해야 하는지에 대한 정보를 확보할 수 있습니다.

Bean 정의

우선, 클래스를 Bean으로 사용할 것을 명시하는 과정이 필요합니다. 이 과정을 'Bean을 정의한다'라고 합니다. Bean 정의는 Annotation 방식과 Java Code 방식으로 수행할 수 있습니다.

Annotaion 방식

다음 사진과 같이 @Component 어노테이션을 활용하는 방법입니다. 해당 방법은 주로 애플리케이션 로직(Service, Repository, Controller)을 담당하는 클래스를 Bean으로 정의하는 경우에 사용합니다.

@Service, @Repository, @Controller

@Service, @Repository, @Controller는 특정 계층을 의미하는 스테레오 타입 어노테이션입니다. 내부적으로 @Component를 포함하고 있기 때문에 이를 사용해도 Bean을 정의할 수 있습니다.

Java Code 방식

다음 사진과 같이 @Cofiguration 클래스와 @Bean 어노테이션을 활용하는 방법입니다. 해당 방법은 주로 외부 라이브러리나 복잡한 생성 로직이 필요한 객체를 Bean으로 정의하는 경우에 사용합니다.

BeanDefinition 객체 변환

IoC 컨테이너는 @ComponentScan을 수행하여 Bean 정의를 읽어 해당 클래스의 메타데이터를 기반으로 BeanDefinition 객체로 변환합니다. 이는 다음 그림과 같은 흐름으로 진행됩니다.

위 과정을 통해 변환되어 IoC 컨테이너 내부에 저장되어 관리되고 있는 BeanDefinition은 추후 실제 Bean 생성 및 관리 과정에서 활용됩니다.

Bean 생성

해당 과정은 일반적으로 사용하는 ApplicationContext를 기준으로 설명하도록 하겠습니다.

IoC 컨테이너는 초기화 시점에BeanDefinition을 기반으로 Bean을 생성하는 작업을 수행합니다. 이때 생성된 Bean은 기본적으로 Singleton 스코프를 가지며 필요한 경우 다른 스코프로 지정할 수도 있습니다. 이해를 돕기 위해 MemberController를 Bean으로 생성하는 과정을 통해 어떻게 진행되는지 살펴보도록 하겠습니다.

Scope

Scope는 Bean의 생명주기 범위에 대한 설정입니다. 이는 언제,얼마나 자주 생성되고 관리되는지를 결정합니다. 기본적으로 Singleton을 사용하며 Prototype, Request, Session, Application 등이 있습니다.

  • Singleton : 컨테이너 초기화 시점에 생성되고, 컨테이너 종료 시점에 소멸
  • Prototype : Bean 요청마다 생성되고, 개발자가 명시적으로 소멸 메서드 호출할 때 소멸
  • Request : HTTP 요청마다 생성되고, 요청 종료 후 소멸
  • Session : HTTP Session당 생성되고, Session 종료 후 소멸

BeanDefinition 탐색

우선, 다음 그림과 같이 BeanDefinition를 탐색하여 MemberController 클래스에 대한 메타데이터를 가져올 수 있습니다.

Bean 생성

가져온 메타데이터를 통해 해당 클래스의 의존 관계를 파악합니다.

의존 관계가 있지만 이를 충족하기 위한 클래스의 Bean이 아직 없다면, 다음 그림과 같이 해당 클래스에 대한 Bean을 우선 생성합니다.

이후 MemberController에 대한 의존성 주입을 수행하여 Bean 생성을 마무리합니다.

Bean 초기화/소멸

의존성 주입까지 마무리한 Bean을 사용하기에 앞서 초기화 과정이 필요하며, 사용이 끝난 후에는 소멸 과정을 수행해야합니다. 해당 과정에서는 주로 다음과 같은 작업을 수행합니다.

  • 초기화 : 설정값 로드, 외부 리소스(DB, 파일, 네트워크) 연결 등
  • 소멸 : DB 연결 종료, 캐시 데이터 삭제, 스레드 종료 등

콜백 메서드

Spring은 Bean의 초기화와 소멸 과정을 자동으로 관리하기 위해 3가지(어노테이션, 인터페이스, 속성) 방식의 콜백 메서드를 제공합니다.

어노테이션

어노테이션 방식은 Bean의 초기화와 소멸을 처리하기 위해 가장 권장되는 방식으로 @PostConstruct@PreDestroy 어노테이션을 활용합니다. 다음 코드 예시는 데이터베이스 연결을 초기화하고, 소멸 시 연결을 해제하는 과정을 보여줍니다.

인터페이스

인터페이스 방식은 Spring에서 제공하는 InitializingBean, DisposableBean 인터페이스를 활용하는 방식입니다. 이 방식의 경우 Spring에서 제공하는 인터페이스를 사용하기 때문에 종속적이라는 단점이 있어 권장하는 방식은 아닙니다. 다음 코드 예시는 데이터베이스 연결을 초기화하고, 소멸 시 연결을 해제하는 과정을 보여줍니다.

속성

속성 방식은 @Bean 어노테이션의 속성인 initMethoddestroyMethod를 활용하는 방식입니다. 이 방식의 경우 코드 수정 없이 설정 파일을 통해 초기화와 소멸 메서드를 명시적으로 지정할 수 있어 특히 외부 라이브러리를 Bean으로 등록할 때 유용합니다. 다음 코드 예시는 데이터베이스 연결을 초기화하고, 소멸 시 연결을 해제하는 과정을 보여줍니다.

정리

이를 정리하면 다음과 같습니다.

  • Bean 생명주기
    • 등록 -> 생성 -> 초기화 -> 사용 -> 소멸
  • 등록 과정
    • 어노테이션, 자바 코드 기반 방식으로 Bean 정의
    • 컴포넌트 스캔을 통해 정의된 Bean을 BeanDefinition 객체로 변환
  • 생성 과정
    • BeanDefinition을 참조하여 Bean 생성
      • 의존 관계가 있을 경우, 이를 주입 후 Bean 생성 마무리
  • 초기화/소멸 과정
    • Bean을 사용하기 전 초기화 작업, 사용 후 소멸 작업 수행 필요
      • 초기화 작업에선 외부 리소스 연결이나 설정값 로딩 수행
      • 소멸 과정에선 불필요한 Bean을 삭제하여 자원 정리 수행
    • 콜백 메서드를 활용하여 Bean을 사용하기 전 초기화, 사용 후 소멸 작업 수행
      • 어노테이션 방식 (가장 권장)
        • @PostConstruct, @PreDestory 어노테이션 활용
      • 인터페이스 방식
        • afterPropertiesSet, Destory 메서드 오버라이딩
      • 속성 방식 (외부 라이브러리를 Bean으로 등록할 때 권장)
        • @Bean(initMethod="초기화 메서드", destroyMethod="소멸 메서드")

추가 학습이 필요한 내용

아래는 위 개념을 공부하면서 추가 학습이 필요할 것 같은 내용들입니다. 이 내용들은 차차 정리하여 링크를 달도록 하겠습니다.

의존성 주입

예상 질문

Bean 생명주기란?

IoC 컨테이너의 주요 기능으로 Bean을 제어하는 과정을 말합니다. 해당 과정은 등록, 생성, 초기화, 사용, 소멸 단계로 진행됩니다.

등록은 어떻게 진행되나요?

우선, 개발자가 Bean으로 사용할 클래스를 정의하고 컴포넌트 스캔을 통해 클래스를 Bean으로 등록합니다. 해당 과정에서 클래스에 대한 메타데이터를 포함하는 BeanDefinition 객체로 변환되어 IoC 컨테이너 내부에 저장되어 관리됩니다.

생성은 어떻게 진행되나요?

IoC 컨테이너 내부에 있는 BeanDefinition 객체를 참조하여 메타데이터를 가져오고, 이를 통해 의존 관계를 파악한합니다. 이후, 의존성 주입을 수행하여 Bean을 생성합니다.

초기화/소멸 과정은 어떻게 구현하나요?

초기화/소멸 과정은 콜백 메서드 함수를 통해 구현할 수 있습니다. 콜백 메서드는 어노테이션, 속성, 인터페이스 방식이 존재합니다. 이를 통해, Bean을 사용하기 전과 후에 초기화/소멸 과정을 자동으로 관리합니다.

초기화/소멸 과정에서 어떤 작업을 수행하나요?

초기화 작업에서는 주로 설정값을 로드하거나 외부 리소스 연결을 수행하고, 소멸 과정은 스레드 종료, 자원 해제, 캐시 정리등을 수행합니다.

어노테이션 방식은 무엇인가요?

@PostConstruct, @PreDestroy 어노테이션을 활용하여 초기화/소멸 작업을 정의하는 방식으로 가장 권장하는 방식입니다.

속성 방식은 무엇인가요?

@Bean 어노테이션의 속성인 initMethod와 destoryMethod를 사용하여 초기화/소멸 메서드를 지정하는 방식입니다. 주로, 외부 라이브러리를 Bean으로 생성할 때 사용합니다.

인터페이스 방식은 무엇인가요?

Spring에서 제공하는 InitializingBean과 DisposableBean 인터페이스를 구현하는 방식입니다. 이를 통해, addPropertiesSet()과 destroy() 메서드를 오버라이딩하여 초기화/소멸 작업을 정의합니다. 이 방식의 경우 Spring에 종속적이라는 단점을 가지고 있습니다.

Bean의 Scope는 무엇이 있고, 각 특징은 뭔가요?

Scope로는 Singleton, Prototype, Request, Session 등이 있습니다. Spring은 Singleton 방식을 기본적으로 적용하고 있습니다. 4개의 가장 중요한 차이는 생성 시점과 소멸 시점입니다.

Singleton의 경우 컨테이너 생성과 종료 시점에, Prototype의 경우 Bean 요청 시점과 개발자가 정의한 시점에, Request의 경우 HTTP 요청과 종료 시점에, Session의 경우 HTTP Session 요청과 종료 시점에 생성과 소멸이 이루어집니다.

Singleton 외의 다른 Scope를 설정해야 하는 상황은 무엇인가요?

Prototype의 경우 매 요청마다 상태관리가 별도로 필요한 경우, Request의 경우 HTTP 요청마다 상태관리가 필요한 경우, Session은 사용자 세션마다 상태관리가 필요한 경우 필요합니다.

profile
동료들의 시간과 노력을 더욱 빛내줄 수 있는 개발자가 되고자 노력합니다.

0개의 댓글