'초보 웹 개발자를 위한 스프링 5 프로그래밍 입문' 챕터 5를 읽고 정리한 내용입니다.
Spring에서는 스프링 컨테이너가 빈(Bean)의 생성부터 소멸까지의 전 과정을 관리한다. 빈(Bean)은 스프링 컨테이너의 라이프사이클을 따르며, 객체가 생성된 후 초기화되고, 컨테이너가 종료되면 소멸된다. 또한, 스프링 빈의 범위(Scope) 에 따라 동일한 객체를 공유할 수도 있고, 새로운 객체를 매번 생성할 수도 있다.
이 글에서는 스프링 빈의 라이프사이클과 범위에 대해 자세히 알아본다.
1. 스프링 컨테이너와 빈의 라이프사이클
스프링 컨테이너의 역할
스프링 컨테이너는 설정 클래스를 읽어 빈 객체를 생성하고, 각 빈을 연결(의존 주입)하며, 전체 라이프사이클을 관리한다.
즉, 스프링 컨테이너의 라이프사이클에 따라 빈 객체도 생성과 소멸이라는 라이프사이클을 갖는다.
빈의 라이프사이클 단계
- 빈 객체 생성 → 컨테이너가 설정 정보를 읽고, 빈 객체를 생성
- 의존성 주입(DI, Dependency Injection) → 생성된 빈에 필요한 의존 객체를 주입
- 초기화(Initialization) → 빈이 사용 준비 완료 (ex. DB 연결, 설정값 로드)
- 사용(Usage) → 빈 객체가 컨테이너 내부에서 사용됨
- 소멸(Destruction) → 컨테이너 종료 시 빈이 소멸됨 (ex. DB 연결 해제, 리소스 정리)
예시) 데이터베이스 연결 관리
@Component
public class DatabaseConnection {
public void connect() {
System.out.println("데이터베이스 연결 완료");
}
public void close() {
System.out.println("데이터베이스 연결 해제");
}
}
초기화 단계에서 데이터베이스 연결이 생성되고, 사용 단계에서 연결 유지, 소멸 단계에서 연결 해제된다.
2. 빈 라이프사이클 인터페이스 (InitializingBean, DisposableBean)
스프링 컨테이너는 빈 객체의 초기화 및 소멸 시, 특정 메서드를 호출하여 라이프사이클을 관리한다. 이를 위해 Spring에서는 InitializingBean, DisposableBean 인터페이스를 제공한다.
빈 객체의 초기화 (InitializingBean 인터페이스)
InitializingBean 인터페이스를 구현하면 빈이 초기화될 때 afterPropertiesSet() 메서드가 자동으로 호출된다.
@Component
public class ExampleBean implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("빈 초기화 완료!");
}
}
컨테이너가 빈을 생성한 후 afterPropertiesSet() 메서드를 실행하여 초기화 작업 수행한다.
빈 객체의 소멸 (DisposableBean 인터페이스)
DisposableBean 인터페이스를 구현하면 빈이 소멸될 때 destroy() 메서드가 자동으로 호출된다.
@Component
public class ExampleBean implements DisposableBean {
@Override
public void destroy() throws Exception {
System.out.println("빈 소멸!");
}
}
컨테이너가 종료되면 destroy() 메서드가 실행되어 리소스를 정리한다.
3. @Bean을 사용한 커스텀 초기화 및 소멸 메서드 지정
위 인터페이스를 구현하지 않더라도, 설정 클래스에서 @Bean을 사용하여 직접 초기화 및 소멸 메서드를 지정할 수 있다.
@Bean(initMethod, destroyMethod) 사용
@Configuration
public class AppConfig {
@Bean(initMethod = "connect", destroyMethod = "close")
public DatabaseConnection databaseConnection() {
return new DatabaseConnection();
}
}
- initMethod = "connect" → 빈이 생성될 때 connect() 메서드를 실행
- destroyMethod = "close" → 빈이 소멸될 때 close() 메서드를 실행
@PostConstruct, @PreDestroy 애노테이션 활용
Spring에서는 @PostConstruct와 @PreDestroy 애노테이션을 활용해 초기화와 소멸 메서드를 지정할 수도 있다.
@Component
public class ExampleBean {
@PostConstruct
public void init() {
System.out.println("빈 초기화 완료!");
}
@PreDestroy
public void destroy() {
System.out.println("빈 소멸!");
}
}
- @PostConstruct → 빈이 생성될 때 실행
- @PreDestroy → 빈이 소멸될 때 실행
4. 스프링 빈의 범위(Scope)
스프링 컨테이너는 기본적으로 모든 빈을 하나만 생성(싱글톤) 한다. 하지만, 특정 상황에서는 매번 새로운 인스턴스를 생성해야 하는 경우도 있다. 이때, 빈의 범위(Scope) 를 지정하면 생성 방식이 달라진다.
빈의 범위 (Scope) 종류
singleton (기본값) | 컨테이너에서 한 번만 생성 (전역적으로 공유) |
prototype | 빈을 요청할 때마다 새로 생성 |
request | HTTP 요청별로 새로운 빈 생성 (웹 애플리케이션) |
session | HTTP 세션별로 새로운 빈 생성 (웹 애플리케이션) |
singleton (기본값)
singleton 스코프는 컨테이너 내에서 단 하나의 인스턴스만 유지한다.
@Bean
@Scope("singleton")
public DatabaseConnection databaseConnection() {
return new DatabaseConnection();
}
컨테이너가 시작될 때 단 한 개의 빈을 생성하여, 모든 요청에서 동일한 객체를 참조한다.
prototype (매번 새로운 객체 생성)
prototype 스코프를 지정하면 매번 빈을 요청할 때마다 새로운 인스턴스가 생성된다.
@Bean
@Scope("prototype")
public DatabaseConnection databaseConnection() {
return new DatabaseConnection();
}
새로운 요청이 발생할 때마다 새로운 객체가 생성되어 각 요청에서 독립적인 상태를 유지 할 수 있다.
다만, 스프링 컨테이너가 소멸 메서드를 관리하지 않아, 개발자가 직접 리소스 정리해야 한다.
'Backend' 카테고리의 다른 글
[Spring] Spring DB 연동: JDBC vs JPA (0) | 2024.12.14 |
---|---|
[Spring] 컴포넌트 스캔(자동 빈 등록 과정)이란? (0) | 2024.12.05 |
[Spring] DI(Dependency Injection); 의존 주입이란? (0) | 2024.12.02 |