이 문장은 Spring 실무에서 거의 경고문에 가깝습니다.

빈 라이프사이클을 모르면 버그는 ‘느낌’으로만 잡는다

왜냐하면 Spring에서 버그의 상당수는
로직이 아니라 “언제 생성되고, 언제 연결되고, 언제 호출되느냐” 문제라서요.


1️⃣ 빈 라이프사이클을 모르면 생기는 전형적인 착각

❌ “코드는 맞는데 왜 안 되지?”

  • @Autowired 했는데 null
  • 값이 초기화 안 된 것처럼 보임
  • 어떤 환경에서는 되고, 어떤 환경에서는 안 됨

타이밍 문제입니다.


❌ “어제는 됐는데 오늘은 안 됨”

  • 로컬 OK / 운영 FAIL
  • 단건 호출 OK / 트래픽 시 FAIL
  • 테스트 OK / 배치에서 FAIL

빈 스코프 / 프록시 / 초기화 순서 문제일 확률 높음.


2️⃣ Spring 빈 라이프사이클 핵심 흐름 (실무용)

정석 다 외울 필요 없습니다.
아래만 머리에 들어있으면 80% 잡습니다.

 
1. 빈 정의 로딩 2. 빈 인스턴스 생성 (new) 3. 의존성 주입 (@Autowired) 4. 초기화 콜백 - @PostConstruct - InitializingBean.afterPropertiesSet() 5. 프록시 적용 (@Transactional, AOP) 6. 컨테이너에 등록 → 사용 가능

👉 프록시는 “초기화 이후”에 붙는다
이거 모르면 트랜잭션/보안 버그 절대 못 잡습니다.


3️⃣ ‘느낌 디버깅’이 되는 대표 사례들

1. @PostConstruct에서 트랜잭션 안 걸림

  • “왜 @Transactional 안 먹지?”
  • 이유: 자기 자신 호출 + 프록시 미적용 시점

2. @Autowired 필드가 null

  • 생성자에서 사용
  • 이유: 주입은 생성자 이후

3. @Async / @Transactional 메서드 안 먹음

  • 같은 클래스 내부 호출
  • 이유: 프록시는 외부 호출만 가로챔

4. prototype 빈이 싱글톤처럼 동작

  • 기대: 매번 새 객체
  • 현실: 싱글톤 빈이 한 번만 주입

4️⃣ 빈 라이프사이클을 아는 사람의 디버깅 방식

❌ 느낌 디버깅

  • 로그 찍어봄
  • 재시작해봄
  • 어제 코드랑 비교
  • “환경 문제 같은데요…”

✅ 구조 디버깅

  • 이 빈은 언제 생성되나?
  • 프록시는 언제 붙나?
  • 호출 주체는 컨테이너 밖인가 안인가?
  • 스코프가 뭐지?

👉 원인 후보가 바로 좁혀짐


5️⃣ 실무에서 최소로 알아야 할 포인트 5개

이건 암기 가치 있습니다.

  1. 생성자 주입이 기본
  2. @PostConstruct는 프록시 이전
  3. AOP는 외부 호출만
  4. 빈 스코프는 주입 시점에 결정
  5. 컨테이너 밖 객체에는 Spring이 없다

6️⃣ 한 줄 요약 (설계/회고용)

  • “Spring 버그의 절반은 생명주기 문제다.”
  • “라이프사이클을 알면, 증상이 아니라 원인을 본다.”
  • “모르면 코드를 고치고, 알면 구조를 고친다.”

 

Spring에서 ‘언제’는 ‘무엇’보다 중요하다

LIST

+ Recent posts