Spring 빈 생성 순서가 꼬였을때 확인 방법

정원식·2024년 12월 25일
post-thumbnail

개요

  • 최근 프로젝트에서 의도하지 않은 빈 생성 순서 변경이 일어나 수정한 적이 있습니다.
  • 해당 경우에 도움이 될것으로 보입니다.

준비물

  • Intellij IDEA

결론

  • @AutoConfiguration@Order 는 빈 생성 순서에 영향을 미치지 않습니다.
  • 반면, @DependsOn 은 명시적으로 빈 생성 순서에 영향을 미칩니다.
  • 빈 생성 순서가 꼬인 경우, 아래 방법중 한가지로 순서를 확인하세요
    1. AbstractAutowireCapableBeanFactory#createBean + 디버거
    2. Actuator 의 BeansEndpoint 활용 (/actuator/beans)

문제 케이스

  • 진행하는 프로젝트에서 Prometheus Metric 이 누락되는 이슈가 확인되었습니다.

  • 확인 결과, MeterRegistryPostProcessorMeterRegistry 보다 늦게 등록되어 MeterRegistry 의 후처리를 수행하지 않은것이 원인이었습니다.

    • 그러나 MeterRegistryPostProcessor (MetricsAutoConfiguration) 의 순서는 MeterRegistry (PrometheusMetricsExportAutoConfiguration) 보다 뒤였습니다. (after)
  • 왜 순서가 꼬이게 되었을까요?

원인 & 디펜던시 확인 방법

  • @AutoConfiguration@Order 는 빈 생성 순서에 영향을 미치지 않습니다.
    • @AutoConfiguration 은 빈이 정의되는 순서에만 영향을 미칩니다.
    • @Order 는 주입 시점에만 영향을 미칩니다.
  • 따라서 다른 빈이 생성되기 위해서 MeterRegistry 를 생성하게 된것으로 보입니다.
  • 그렇다면 어떠한 빈이 생성되는 과정에서 MeterRegistry 를 생성하게 되었을까요?
  • 아래 두가지 방법을 통해 확인 가능합니다.

방법1 (디버거로 확인)

  1. 대상 빈을 생성하는 지점에 BreakPoint 를 걸어줍니다.
    • Spring Boot 컴포넌트인 경우,
      1. External Libraries 에서 Spring Boot 디펜던시를 찾아 아무 클래스나 연뒤에 우측 상단의 Download Sources 버튼을 클릭합니다.
      2. 이후 해당 인터페이스를 구현한 빈을 생성하는 AutoConfiguration 을 찾아줍니다.
  2. 디버깅 모드로 애플리케이션을 실행후, Break Point 에서 멈추기까지 대기합니다.
  3. org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean 을 클릭합니다.
    아래처럼 스택내에서 몇번째 호출되었는지와 생성중인 빈 이름이 노출됩니다.

    위의 경우 17번째 호출되었으며 prometheusMeterRegistry 빈이 생성중인것으로 보입니다.
  4. AbstractAutowireCapableBeanFactory#createBean 을 타고 내려가면서 원인이 되는 빈을 확인합니다.

방법2 (/actuator/beans 확인) - 비추천

  • Actuator 의 BeansEndpoint(/actuator/beans) 활용해서도 빈 사이의 디펜던시 확인은 가능합니다.

  • 그러나 너무 많은 빈 사이의 디펜던시가 노출되어 비추천합니다.

수정 방법

  • 순환 참조되는 경우와 유사한 방법으로 수정 가능합니다.
    • org.springframework.beans.factory.ObjectProvider
    • org.springframework.context.annotation.Lazy
  • 위 상황의 경우, ObjectProvider 를 활용하여 해결하였습니다.
profile
매일매일 성장하고 싶은 백엔드 개발자입니다.

0개의 댓글