Spring Boot 실무 가이드 · Part 2

프로젝트 시작과 실행 구조

프로젝트가 어떻게 만들어지고 어떤 순서로 실행되는지 이해하기

작성 기준2026년 7월버전과 지원 현황은 이후 달라질 수 있으니 공식 문서를 함께 확인하세요.

이 파트에서 다루는 내용

프로젝트 생성빌드 도구와 스타터@SpringBootApplication실행 순서와 패키지 구조
01

프로젝트는 Spring Initializr로 시작합니다

직접 폴더를 만들고 의존성을 적는 대신 start.spring.io에서 생성합니다. IntelliJ IDEA와 STS에도 같은 기능이 들어 있어 IDE 안에서 바로 만들 수 있습니다.

여기서 고르는 값들이 이후 프로젝트 성격을 결정합니다. 특히 Java 버전과 Spring Boot 버전은 나중에 바꾸기 번거로우므로 팀 기준을 먼저 확인해야 합니다.

Project
빌드 도구

Gradle 또는 Maven. 팀이 이미 쓰는 쪽을 따릅니다. 혼자 시작한다면 최근 신규 프로젝트는 Gradle 비중이 높습니다.

Spring Boot 버전
가장 중요

지원 종료된 버전으로 새 프로젝트를 시작하지 않습니다. 목록에 SNAPSHOT이나 M(마일스톤) 표시가 붙은 버전은 운영용으로 고르지 않습니다.

Java 버전
런타임 기준

Boot 3.x·4.x 모두 최소 17입니다. 운영 서버의 JDK 버전과 반드시 맞춰야 합니다.

Dependencies
스타터 선택

Spring Web, Spring Data JPA, Validation, Lombok처럼 필요한 것만 고릅니다. 나중에 추가할 수 있으니 처음부터 다 넣지 않습니다.

02

스타터는 라이브러리 묶음이자 버전 관리 장치입니다

spring-boot-starter-web 하나를 추가하면 웹 개발에 필요한 라이브러리가 함께 들어옵니다. 스프링 웹 MVC, 내장 톰캣, JSON 처리기가 세트로 구성됩니다.

더 중요한 것은 버전입니다. 각 라이브러리 버전을 개별로 적지 않아도, Spring Boot가 검증한 조합을 자동으로 맞춰 줍니다. 버전 충돌로 며칠을 쓰던 문제가 여기서 크게 줄었습니다.

자주 쓰는 스타터
참고
  • starter-web: REST API와 웹 MVC
  • starter-data-jpa: JPA와 Hibernate
  • starter-validation: 요청 값 검증
  • starter-security: 인증과 인가
  • starter-actuator: 운영 엔드포인트
  • starter-test: JUnit, Mockito, 테스트 지원
주의할 점
실무
  • 필요 없는 스타터는 넣지 않습니다. 특히 security는 추가하는 순간 모든 요청에 인증이 걸립니다
  • 라이브러리 버전을 임의로 올리면 호환성 검증 범위를 벗어납니다
  • 사내 폐쇄망이면 의존성 저장소 미러 설정을 먼저 확인합니다
build.gradle 기본 구성gradle
plugins {
    id "java"
    id "org.springframework.boot" version "3.5.0"
    id "io.spring.dependency-management" version "1.1.7"
}

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

dependencies {
    implementation "org.springframework.boot:spring-boot-starter-web"
    implementation "org.springframework.boot:spring-boot-starter-validation"
    runtimeOnly "com.h2database:h2"
    testImplementation "org.springframework.boot:spring-boot-starter-test"
}

스타터에 버전을 적지 않은 점을 보세요. 버전은 Spring Boot 플러그인이 관리합니다. 임의로 버전을 지정하면 검증된 조합이 깨질 수 있습니다.

03

@SpringBootApplication 한 줄에 세 가지가 들어 있습니다

메인 클래스에 붙는 @SpringBootApplication은 사실 세 애노테이션을 합친 것입니다. 이 구성을 알아야 '왜 내 클래스가 빈으로 안 잡히지?' 같은 문제를 스스로 풀 수 있습니다.

@SpringBootConfiguration
설정 클래스 표시

이 클래스가 설정 정보를 담은 클래스임을 알립니다. @Configuration의 Boot 전용 버전입니다.

@EnableAutoConfiguration
자동 설정 활성화

클래스패스와 이미 등록된 빈을 근거로 필요한 설정을 자동 등록합니다. Boot의 핵심 동작입니다.

@ComponentScan
빈 탐색

메인 클래스가 위치한 패키지와 그 하위 패키지를 훑어 @Component 계열 클래스를 빈으로 등록합니다.

패키지 배치 기준text
com.example.order          <- 메인 클래스 위치 (스캔 기준점)
├─ OrderApplication.java
├─ controller
├─ service
├─ repository
└─ domain

com.example.common         <- 스캔되지 않음. 별도 설정 필요

메인 클래스를 최상위에 두면 하위 패키지가 모두 스캔 범위에 들어옵니다. 별도 모듈을 쓰려면 scanBasePackages를 지정하거나 설정 클래스를 명시적으로 import 합니다.

실무에서 자주 막히는 지점

컴포넌트 스캔 범위는 메인 클래스가 있는 패키지 아래입니다. 메인 클래스를 com.example.api에 두고 서비스 클래스를 com.example.core에 두면 빈으로 등록되지 않습니다. 메인 클래스는 항상 최상위 패키지에 두는 것이 안전합니다.

04

실행 순서를 알면 기동 실패 로그가 읽힙니다

java -jar로 실행하면 눈에 보이지 않는 순서가 진행됩니다. 이 순서를 알면 어느 단계에서 실패했는지 로그로 판단할 수 있습니다.

  • 1. main 메서드에서 SpringApplication.run 호출
  • 2. 웹 환경인지 판단하고 적절한 애플리케이션 컨텍스트 생성
  • 3. 컴포넌트 스캔으로 빈 정의 수집, 자동 설정 적용
  • 4. 빈 생성과 의존성 주입 수행 (여기서 순환 참조·빈 누락 오류 발생)
  • 5. 내장 서버 기동 및 포트 바인딩 (여기서 포트 충돌 오류 발생)
  • 6. ApplicationRunner·CommandLineRunner 실행 후 대기 상태 진입
빈 생성 단계 실패
4단계

"Parameter 0 of constructor ... required a bean of type ... that could not be found" 형태입니다. 빈 등록 누락이나 컴포넌트 스캔 범위를 확인합니다.

포트 충돌
5단계

"Web server failed to start. Port 8080 was already in use" 입니다. 이미 실행 중인 프로세스를 종료하거나 server.port를 변경합니다.

DB 연결 실패
자동 설정

DataSource 자동 설정은 되는데 접속 정보가 없으면 기동이 실패합니다. 설정값 누락인지 네트워크 문제인지 구분해서 봅니다.

05

패키지 구조는 계층형과 도메인형 중에 고릅니다

계층형
controller / service / repository

역할별로 묶습니다. 익숙하고 처음 보는 사람도 위치를 짐작하기 쉽습니다. 다만 기능이 늘면 한 패키지에 서로 관련 없는 클래스가 쌓입니다.

  • 소규모 프로젝트
  • 팀원이 구조에 익숙할 때
  • 학습·예제 코드
도메인형
order / member / payment

업무 단위로 묶고 그 안에서 계층을 나눕니다. 기능 하나를 수정할 때 한 패키지 안에서 끝나고, 나중에 모듈 분리도 쉽습니다.

  • 기능이 계속 늘어나는 서비스
  • 여러 명이 나눠 개발할 때
  • 장기 유지보수 대상
선택 기준

정답은 없지만 프로젝트가 커질수록 도메인형이 유리합니다. 중요한 것은 팀이 하나를 정하고 일관되게 지키는 것입니다. 구조가 섞이면 새로 합류한 사람이 파일을 찾지 못합니다.

버전

3.x와 4.x 차이

본문은 현장에서 가장 많이 쓰는 3.x 기준입니다. 4.x에서 달라진 부분만 아래에 정리합니다.

  • 3.x에서는 spring-boot-autoconfigure 하나에 대부분의 자동 설정이 들어 있습니다.
  • 4.0부터 자동 설정이 기술별 모듈로 분리됐습니다. 필요한 모듈만 포함되므로 의존성이 가벼워지지만, 기존 프로젝트를 올릴 때는 빠진 모듈을 추가해야 하는 경우가 생깁니다.
  • Initializr에서 4.x를 고르면 스타터 구성이 3.x와 다르게 잡힐 수 있습니다. 사내 예제 코드가 3.x 기준이면 그대로 복사하지 말고 의존성부터 확인합니다.
체크

이 파트 완료 기준