스프링 빈의 라이프사이클은 크게 다음과 같은 단계로 나뉩니다.
스프링 IoC 컨테이너는 빈의 라이프사이클을 전적으로 관리하며, 필요한 메서드를 실행하거나 콜백을 호출하여 초기화 및 소멸 과정을 처리합니다.
@PostConstruct
어노테이션이나 init-method
속성으로 지정할 수 있습니다. 이 단계에서 빈이 필요한 준비 작업을 수행하여 사용할 준비가 됩니다.@PreDestroy
어노테이션이나 destroy-method
속성을 통해 소멸 메서드를 지정할 수 있습니다. 소멸 메서드는 자원 해제 및 정리 작업을 수행합니다.빈의 초기화와 소멸 과정에서 콜백 메서드를 설정할 수 있습니다. 스프링은 초기화와 소멸을 위해 다양한 방법을 제공합니다.
InitializingBean
인터페이스의 afterPropertiesSet()
메서드를 통해 초기화 작업을 설정할 수 있습니다.DisposableBean
인터페이스의 destroy()
메서드를 통해 소멸 작업을 설정할 수 있습니다.@PostConstruct
와 @PreDestroy
어노테이션 사용:@PostConstruct
: 빈의 초기화 메서드를 지정합니다.@PreDestroy
: 빈의 소멸 메서드를 지정합니다.init-method
와 destroy-method
속성:<bean>
태그의 init-method
와 destroy-method
속성을 통해 초기화 및 소멸 메서드를 지정할 수 있습니다.스프링에서 빈은 싱글톤(Singleton)이 기본 스코프로 설정되지만, 여러 가지 스코프를 제공하여 객체 관리 방식을 다르게 할 수 있습니다.
다음은 @PostConstruct
와 @PreDestroy
어노테이션을 사용하여 초기화 및 소멸 과정을 지정하는 예제입니다.
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class ExampleBean {
public ExampleBean() {
System.out.println("ExampleBean 생성자 호출");
}
@PostConstruct
public void init() {
System.out.println("ExampleBean 초기화 메서드 호출");
}
public void performTask() {
System.out.println("ExampleBean의 비즈니스 로직 수행");
}
@PreDestroy
public void destroy() {
System.out.println("ExampleBean 소멸 메서드 호출");
}
}
위의 예제를 XML 설정에서 초기화 및 소멸 메서드를 지정하는 방법은 다음과 같습니다.
<bean id="exampleBean" class="org.example.ExampleBean" init-method="init" destroy-method="destroy"/>
init-method="init"
: init
메서드를 초기화 단계에서 호출합니다.destroy-method="destroy"
: destroy
메서드를 소멸 단계에서 호출합니다.이러한 설정을 통해 스프링은 빈의 생명 주기를 전적으로 관리하게 되며, 개발자는 객체 생성 및 소멸에 필요한 작업을 코드 수정 없이 설정할 수 있습니다.
package org.example.lifecycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
// 빈의 생성, 소멸 과정 InitializingBean, DisposableBean,
// 중간 설정 과정 ApplicationContextAware, BeanNameAware, BeanClassLoaderAware, BeanFactoryAware
public class WriteAction implements Action, InitializingBean, DisposableBean, ApplicationContextAware, BeanNameAware, BeanClassLoaderAware, BeanFactoryAware {
String writer;
public WriteAction() {
System.out.println("1. 생성자 호출");
}
public void setWriter(String writer) {
System.out.println("2. setWriter(String writer) 호출");
this.writer = writer;
}
@Override
public void execute() {
System.out.println("*. exectue() 호출");
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("4. setBeanClassLoader(ClassLoader classLoader) 호출");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("5. setBeanFactory(BeanFactory beanFactory) 호출");
}
@Override
public void setBeanName(String name) {
System.out.println("3. setBeanName(String name) 호출");
// 빈 이름을 세팅
System.out.println("Bean name = " + name);
}
@Override
public void destroy() throws Exception {
System.out.println("11. destroy() 호출");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("8. afterPropertiesSet() 호출");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("6. setApplicationContext(ApplicationContext applicationContext) 호출");
}
// 빈의 생성과 소멸에 추가 작동
public void initMethod() {
System.out.println("9. initMethod() 호출 (개별 빈 커스팀 초기화 시)");
System.out.println("빈 커스텀 초기화");
}
public void destroyMethod() {
System.out.println("12. destroyMethod 호출 (개별 빈 커스텀 소멸 시)");
System.out.println("빈 커스텀 소멸화");
}
}
package org.example.lifecycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class CustomBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("7. 초기화 전의 빈에 대한 처리 (전체)");
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("10. 초기화 후의 빈에 대한 처리 (전체)");
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
}
객체 생성 단계
1. 생성자 호출
프로퍼티 설정 단계
setWriter(String writer)
메서드를 호출합니다.2. setWriter(String writer) 호출
Aware 인터페이스를 통한 스프링 환경 정보 설정 단계
3. setBeanName(String name) 호출
Bean name = writeAction
4. setBeanClassLoader(ClassLoader classLoader) 호출
5. setBeanFactory(BeanFactory beanFactory) 호출
6. setApplicationContext(ApplicationContext applicationContext) 호출
초기화 전 빈에 대한 공통 처리 (BeanPostProcessor)
postProcessBeforeInitialization
메서드를 통해 빈 초기화 전 작업을 처리합니다. 이 메서드는 모든 빈에 대해 공통적인 작업을 수행할 수 있습니다.7. 초기화 전의 빈에 대한 처리 (전체)
InitializingBean을 통한 초기화 (afterPropertiesSet)
afterPropertiesSet()
메서드가 호출됩니다. 이 메서드는 빈의 초기화 작업을 수행하며, 모든 속성 설정이 완료된 후에 호출됩니다.8. afterPropertiesSet() 호출
커스텀 초기화 메서드 (initMethod)
initMethod()
가 호출됩니다. 이 메서드는 사용자 정의 초기화 메서드로, 초기화가 필요한 추가 작업을 지정할 수 있습니다.9. initMethod() 호출 (개별 빈 커스팀 초기화 시)
빈 커스텀 초기화
초기화 후 빈에 대한 공통 처리 (BeanPostProcessor)
postProcessAfterInitialization
메서드를 통해 빈 초기화 후 작업을 수행합니다.10. 초기화 후의 빈에 대한 처리 (전체)
빈 사용 단계
execute()
메서드를 호출하여 빈의 기능을 수행할 수 있습니다.*. execute() 호출
빈 소멸 단계 (destroy)
destroy()
메서드를 호출하여 빈의 소멸 작업을 수행합니다.11. destroy() 호출
커스텀 소멸 메서드 (destroyMethod)
destroyMethod()
가 호출됩니다. 이 메서드는 빈이 소멸될 때 필요한 추가적인 정리 작업을 수행합니다.12. destroyMethod 호출 (개별 빈 커스텀 소멸 시)
빈 커스텀 소멸화
위에서 설명한 단계들을 전체적으로 보면 다음과 같은 라이프사이클 흐름이 완성됩니다:
1. 생성자 호출
2. setWriter(String writer) 호출
3. setBeanName(String name) 호출
4. setBeanClassLoader(ClassLoader classLoader) 호출
5. setBeanFactory(BeanFactory beanFactory) 호출
6. setApplicationContext(ApplicationContext applicationContext) 호출
7. 초기화 전의 빈에 대한 처리 (전체)
8. afterPropertiesSet() 호출
9. initMethod() 호출 (개별 빈 커스팀 초기화 시)
10. 초기화 후의 빈에 대한 처리 (전체)
*. execute() 호출 (빈 사용 단계)
11. destroy() 호출
12. destroyMethod 호출 (개별 빈 커스팀 소멸 시)
이와 같은 단계적 생명주기 과정을 통해 스프링 프레임워크는 빈 객체의 생성부터 소멸까지 완전한 제어를 제공하여, 개발자가 빈의 라이프사이클을 효율적으로 관리할 수 있도록 돕습니다.