개발하는 재규어
article thumbnail
반응형

Spring Bean Lifecycle 완벽 정리 (생성부터 소멸까지 + @PostConstruct, @PreDestroy)

Intro ⭐

 Spring을 사용하다 보면 Bean 객체를 생성하고 주입받아 사용하는 경우가 대부분입니다.
특히 Spring Bean Lifecycle(빈 생명주기)은 객체가 언제 생성되고, 언제 초기화되며, 언제 소멸되는지를 결정하는 중요한 개념입니다.
예를 들어, 서버 기동 시 공통 코드를 미리 캐싱하거나, 외부 API 연결을 초기화하는 작업은 Bean Lifecycle을 이해해야만 올바르게 구현할 수 있습니다.

 하지만 많은 경우 생성자와 초기화 시점(@PostConstruct)의 차이를 정확히 이해하지 못해 의도하지 않은 오류가 발생하기도 합니다.
이번 글에서는 Spring Bean Lifecycle의 전체 흐름과 함께, 실무에서 자주 사용하는 초기화/소멸 방법을 정리해보겠습니다.

 


 

Spring Bean이란?

 Spring에서 Bean이란, Spring IoC 컨테이너가 관리하는 객체를 의미합니다.
개발자가 직접 new 키워드로 생성하는 객체가 아니라, Spring이 생성하고 관리하며 의존성 주입(DI)까지 수행하는 객체입니다.

 대표적으로 @Service, @Controller, @Repository 등의 어노테이션이 붙은 클래스들이 Bean으로 등록됩니다.

위와 같이 선언된 클래스는 Spring이 Bean으로 생성하여 관리하게 됩니다.

@Service
public class UserService {

}

 

Spring Bean Lifecycle 흐름

Spring Bean Lifecycle은 다음과 같은 순서로 동작합니다.

 

객체 생성 → 의존성 주입 (DI) → 초기화 (@PostConstruct) → 사용 → 소멸 (@PreDestroy)

 

각 단계는 다음과 같은 의미를 가집니다.

  • 객체 생성: 생성자 호출
  • 의존성 주입: @Autowired 등을 통해 의존 객체 주입
  • 초기화: @PostConstruct 실행
  • 사용: 실제 비즈니스 로직 수행
  • 소멸: @PreDestroy 실행

 


 

@PostConstruct (초기화)

@PostConstruct는 Bean이 생성되고 의존성 주입이 완료된 이후 실행되는 초기화 메소드입니다.

import jakarta.annotation.PostConstruct;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    public UserService() {
        System.out.println("1. 생성자 호출");
    }

    @PostConstruct
    public void init() {
        System.out.println("2. 초기화 메소드 실행");
    }
}

실행 순서는 다음과 같습니다.

1. 생성자 호출
2. 초기화 메소드 실행

즉, @PostConstruct는 DI 이후 실행되므로 초기화 로직을 작성하기에 가장 적합한 위치입니다.

 


 

@PreDestroy (소멸)

@PreDestroy는 Bean이 소멸되기 직전에 실행되는 메소드입니다.

import jakarta.annotation.PreDestroy;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @PreDestroy
    public void destroy() {
        System.out.println("리소스 정리");
    }
}

서버 종료 시 호출되며, 커넥션 종료나 자원 정리에 사용됩니다.

 


 

Honey Tip 🍯

@PostConstruct가 Spring Bean 초기화 과정에서 동기적으로 실행되기 때문에, @PostConstruct에서 DB 작업이나 외부 API 호출과 같은 무거운 로직을 수행할 경우, 서버 기동 속도가 느려지거나 장애가 발생할 수 있습니다.

@PostConstruct
public void init() {
    // 외부 API 호출, 대상 서버에 연결을 실패 할 경우 Bean 초기화가 멈추거나 서버 실행 불가
    restTemplate.getForObject("https://api.example.com/data", String.class);
}


즉, 해당 로직이 완료되기 전까지는 다음 Bean 초기화 및 서버 기동이 지연될 수 있기 때문에 @PostConstruct에는 가벼운 초기화 로직만 수행하는 것이 바람직합니다.

 


 

해당 게시글은 독학을 통해 얻은 지식들을 취합하여 작성한 글입니다.
잘못된 내용이 있을 경우 댓글을 통해 지적을 해주신다면 저와, 이 글을 참조하게 될 모든 분들께 큰 힘이 됩니다.
반응형
profile

개발하는 재규어

@Dev.Jaguar

방문해 주셔서 감사합니다! 오늘도 좋은 하루 되세요 :)

profile on loading

Loading...