Spring

Spring Bean 라이프사이클에 대해서 설명해주세요

생성부터 소멸까지 14단계 흐름, @PostConstruct·@PreDestroy, BeanPostProcessor의 AOP 프록시 생성까지. 면접에서 자주 묻는 Bean 라이프사이클을 인터랙티브 시각화로 완벽히 준비합니다.

2026년 3월 15일 · 약 10분 읽기

Q. "Spring IoC 컨테이너가 Bean을 어떻게 생성하고 초기화하며 소멸시키는지 설명해주세요."

예상 꼬리질문

답변 가이드

"Spring Bean은 인스턴스화 → 의존성 주입 → 초기화 콜백 → 사용 → 소멸 콜백의 라이프사이클을 거칩니다. IoC 컨테이너가 단순히 new로 만드는 것이 아니라 정교하게 관리합니다."

"초기화 콜백은 @PostConstruct → afterPropertiesSet() → initMethod 순서로 실행됩니다. @PostConstruct가 JSR-250 표준이라 Spring에 의존하지 않아 가장 권장됩니다."

"BeanPostProcessor는 모든 Bean의 초기화 전후에 실행되는 확장 포인트입니다. Spring의 @Transactional, @Cacheable이 이 메커니즘으로 초기화 후 Bean 객체를 프록시 객체로 교체합니다."

@PostConstruct가 없었다면 DB 커넥션 풀은 언제 초기화해야 할까요? 생성자에서 @Autowired 필드를 쓰면 왜 NullPointerException이 날까요?

이 아티클에서는 Bean 라이프사이클 14단계 흐름부터 초기화 콜백 비교, BeanPostProcessor의 AOP 프록시 생성까지 직접 체험하며 이해합니다.


1. Bean 라이프사이클 전체 흐름

꼬리질문: "Spring Bean의 라이프사이클 단계를 순서대로 설명해주세요"

Spring IoC 컨테이너는 Bean을 단순히 new로 만들지 않습니다. 인스턴스화 → 의존성 주입 → Aware 인터페이스 → BeanPostProcessor(전) → 초기화 콜백 → BeanPostProcessor(후) → 사용 → 소멸 콜백 순서로 정교하게 관리합니다.

각 단계를 순서대로 진행되기 때문에, 어느 시점에 어떤 콜백이 실행되는지 파악하면 초기화 버그 대부분을 예방할 수 있습니다.

단계를 클릭하며 각 시점에 무슨 일이 일어나는지 확인해 보세요.

단계 1 / 14생성
1

인스턴스화

Spring 컨테이너가 Bean 클래스의 생성자를 호출해 객체를 생성합니다. 이 시점에는 의존성이 아직 주입되지 않았습니다.

MyBean bean = new MyBean(); // 생성자 호출
완료 현재 대기

2. 초기화 콜백 3가지 비교

꼬리질문: "@PostConstruct, InitializingBean, initMethod의 차이와 실행 순서는?"

초기화 콜백은 세 가지 방법으로 등록할 수 있습니다. @PostConstruct는 JSR-250 표준이라 Spring에 의존하지 않아 권장됩니다. InitializingBean은 Spring 인터페이스 구현이 필요해 결합도가 높습니다. @Bean(initMethod)는 소스 수정이 불가능한 외부 라이브러리 Bean에 유용합니다.

세 방법이 모두 존재할 때 실행 순서는 @PostConstructafterPropertiesSet()initMethod 입니다.

세 방식을 나란히 비교해 보세요.

권장

JSR-250 표준 어노테이션으로 Spring에 의존하지 않습니다. 의존성 주입이 완료된 이후 실행이 보장됩니다.

@Component
public class DatabasePool {
    @Autowired
    private DataSource dataSource;

    @PostConstruct
    public void init() {
        // 의존성 주입 완료 후 실행
        pool = new HikariPool(dataSource);
        log.info("Pool 초기화 완료");
    }
}
장점
  • JSR-250 표준 (Spring 비의존)
  • 코드가 간결하고 직관적
  • 테스트 코드에서 직접 호출 가능
실행 순서
1. @PostConstruct
2. afterPropertiesSet
3. initMethod

3. @PostConstruct가 필요한 이유

꼬리질문: "생성자에서 @Autowired 필드를 쓰면 왜 NPE가 발생하나요?"

생성자에서 @Autowired 필드를 사용하면 NullPointerException이 발생합니다. 필드 주입은 생성자 실행 이후에 이루어지기 때문입니다. @PostConstruct는 의존성 주입이 완료된 이후에 호출되므로 모든 필드가 안전하게 초기화된 상태에서 로직을 실행할 수 있습니다.

더 나은 패턴은 생성자 주입을 사용하는 것입니다. Spring이 생성자 호출 시점에 의존성을 함께 전달하므로, 생성자 내부에서 바로 의존 객체를 사용할 수 있습니다.

주입 방식별로 어느 시점에 필드가 초기화되는지 비교해 보세요.

필드 주입 + @PostConstruct생성자에서 null 위험
@Component
class UserService {
  @Autowired
  private UserRepository repo; // 필드 주입

  public UserService() {
    // repo = null! 위험
  }

  @PostConstruct
  public void init() {
    // repo 안전하게 사용 가능
    repo.findAll();
  }
}
생성자 주입 (권장)즉시 안전
@Component
class UserService {
  private final UserRepository repo;

  // Spring이 생성자 호출 시
  // 의존성 함께 전달
  public UserService(
      UserRepository repo) {
    this.repo = repo;
    repo.findAll(); // 즉시 안전!
  }
}
생성자 주입은 final 필드를 사용할 수 있어 불변성과 테스트 용이성이 높아집니다

4. BeanPostProcessor — 모든 Bean에 공통 로직 적용

꼬리질문: "BeanPostProcessor가 무엇이고 어떻게 AOP 프록시를 만드나요?"

BeanPostProcessor는 컨테이너에 등록된 모든 Bean의 초기화 전/후에 실행되는 확장 포인트입니다. postProcessAfterInitialization()에서 Bean 객체를 프록시 객체로 교체할 수 있습니다.

Spring의 @Transactional, @Cacheable, @Async가 모두 이 방식으로 프록시를 생성합니다. 즉 AOP의 동작 기반이 BeanPostProcessor입니다.

BeanPostProcessor가 Bean을 프록시로 교체하는 과정을 직접 확인해 보세요.

처리 흐름
원본 Bean (UserService)
주요 BeanPostProcessor 구현체
BPP
AutowiredAnnotationBeanPostProcessor
@Autowired 필드 주입 처리
BPP
CommonAnnotationBeanPostProcessor
@PostConstruct / @PreDestroy 처리
BPP
AbstractAdvisorAutoProxyCreator
@Transactional / @Cacheable AOP 프록시 생성

면접 체크리스트

이 항목들을 자신 있게 설명할 수 있다면 Bean 라이프사이클 질문은 준비 완료입니다.

  • - 라이프사이클 순서: 인스턴스화 → 의존성 주입 → Aware → BPP(전) → 초기화 → BPP(후) → 사용 → 소멸
  • - @PostConstruct: 의존성 주입 완료 후 초기화 — DB 커넥션 풀, 캐시 로딩에 사용
  • - 초기화 콜백 순서: @PostConstruct → afterPropertiesSet() → initMethod
  • - @PreDestroy: 컨테이너 종료 전 정리 — Thread Pool, 외부 연결 해제
  • - BeanPostProcessor: 모든 Bean에 공통 처리 — AOP 프록시 생성의 핵심 메커니즘
  • - prototype 스코프: 소멸 콜백 미호출 — 직접 자원 해제 필요

참고 자료


의견을 들려주세요

서비스 개선에 큰 도움이 됩니다. 익명으로 자유롭게 남겨주세요.

0 / 1000