이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.

  • Spring Boot Starter는 자동 설정과 어떤 관계인가?
  • @SpringBootApplication에서 자동 설정이 시작되는 흐름은 무엇인가?
  • 자동 설정을 “마법”이 아니라 조건부 Bean 등록으로 읽는 방법은 무엇인가?

개요

Spring Boot의 생산성은 자동 설정에서 나온다. 하지만 자동 설정은 무작위로 Bean을 만드는 마법이 아니다. classpath에 있는 라이브러리, 사용자가 이미 등록한 Bean, property 값, 애플리케이션 종류를 보고 조건이 맞으면 기본 Bean을 등록하는 구조다.

Starter는 이 자동 설정이 동작할 수 있도록 필요한 의존성을 묶어 준다. spring-boot-starter-web을 추가하면 Spring MVC, Jackson, embedded container 관련 의존성이 들어오고, 이 classpath 상태를 보고 Web MVC 자동 설정이 작동할 수 있다.

시작 흐름

@SpringBootApplication@SpringBootConfiguration, @EnableAutoConfiguration, @ComponentScan을 합친 애너테이션이다. 이 중 자동 설정의 핵심은 @EnableAutoConfiguration이다.

Boot는 자동 설정 후보 목록을 읽고, 각 자동 설정 클래스의 조건을 평가한다. Boot 3 계열에서 이 후보 목록은 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports에 있다. 조건이 맞는 자동 설정은 Bean 등록에 참여하고, 조건이 맞지 않는 자동 설정은 제외된다.

이 구조는 두 가지 장점을 준다. 첫째, 필요한 라이브러리를 추가하면 기본 설정이 자동으로 따라온다. 둘째, 사용자가 직접 설정한 Bean이 있으면 Boot가 물러나는 back-off 규칙으로 커스터마이징이 가능하다. 자동 설정 클래스의 ordering은 Bean 정의 등록 순서에 영향을 주지만, 실제 Bean 생성 순서는 의존성 관계와 lazy 여부에도 좌우된다.

Starter의 역할

Starter는 기능 자체가 아니다. 의존성 큐레이션이다. 예를 들어 web starter를 추가한다고 해서 Starter가 Controller나 DispatcherServlet Bean을 직접 만드는 것이 아니다. Starter가 관련 라이브러리를 classpath에 올리고, Boot의 자동 설정이 그 classpath 조건을 보고 필요한 Bean을 만든다.

이 차이를 알면 의존성 문제를 더 잘 추적할 수 있다. 기능이 동작하지 않을 때는 “Starter가 있나”만 볼 것이 아니라 “자동 설정 조건이 맞나”, “사용자 Bean이 기본 Bean을 대체했나”, “관련 property가 꺼져 있나”를 함께 봐야 한다.

코드 예제

@SpringBootApplication
public class OrderApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
}

이 짧은 코드 안에 component scan과 자동 설정 진입점이 들어 있다. 그래서 프로젝트 시작 코드가 단순해진다. 단순함의 대가는 자동 설정 조건을 읽는 능력이다.

@Bean
public ObjectMapper objectMapper() {
    return JsonMapper.builder()
            .findAndAddModules()
            .build();
}

사용자가 직접 특정 Bean을 등록하면 Boot의 기본 Bean이 물러나는 경우가 많다. 이것이 back-off 설계다. 다만 어떤 Bean 타입과 이름이 자동 설정 조건에 영향을 주는지는 해당 자동 설정 문서를 확인해야 한다.

실전 팁

  • Starter는 의존성 묶음, AutoConfiguration은 조건부 Bean 등록이라고 나누어 기억한다.
  • 기능이 자동으로 켜졌다면 어떤 classpath 조건이 맞았는지 확인한다.
  • 자동 설정을 끄기 전에 property와 사용자 Bean 제공 지점을 먼저 찾는다.
  • 자동 설정 클래스 이름은 기능별로 검색하기 쉽다. 예를 들어 Jackson, WebMvc, DataSource, Security 같은 키워드로 찾는다.
  • Boot 3에서 자동 설정 후보를 추적할 때는 AutoConfiguration.imports와 조건 평가 리포트를 함께 본다.
  • Boot 버전 업그레이드 때는 자동 설정 조건과 기본값 변경을 릴리스 노트와 문서에서 확인한다.

위험 신호!

  • Starter를 추가하고 어떤 Bean이 생겼는지 전혀 확인하지 않는다.
  • 자동 설정이 마음에 들지 않는다는 이유로 관련 자동 설정을 통째로 exclude한다.
  • 사용자 Bean 하나가 기본 자동 설정의 여러 기능을 back-off시킨다는 사실을 모르고 추가한다.
  • spring.factories만 확인하고 Boot 3의 자동 설정 후보를 찾지 못한다.
  • @SpringBootApplication의 scan 범위와 자동 설정을 혼동한다.
  • Boot 문제를 디버그 로그 없이 감으로만 추적한다.

확인 질문

확인 질문

  • Starter와 AutoConfiguration의 차이는 무엇인가?
    • Starter는 의존성 묶음이고 AutoConfiguration은 조건에 따라 Bean을 등록하는 설정 클래스다.
  • @SpringBootApplication에서 자동 설정을 활성화하는 핵심 요소는 무엇인가?
    • @EnableAutoConfiguration이다.
  • 자동 설정을 커스터마이징할 때 먼저 확인할 것은 무엇인가?
    • property 조절 지점과 사용자가 직접 제공할 수 있는 Bean back-off 지점이다.

참고 문서