728x90
반응형

Spring Boot 4.0 핵심 변경점 정리 — Java 25 지원부터 API 버저닝까지

2025년 11월, Spring Boot 4.0이 정식 출시됐다. 단순한 마이너 업데이트가 아니라 Spring Boot의 다음 세대를 여는 메이저 릴리즈다. Spring Framework 7과 Jakarta EE 11 위에 새로 올라섰고, 코드베이스 자체가 재구성됐다. 3.x를 잘 쓰고 있다면 굳이 지금 올려야 하나 고민될 수도 있는데, 결론부터 말하면 지금 당장 옮길 필요는 없지만, 신규 프로젝트라면 4.x로 시작하는 게 합리적이다.

이 글에서는 실무 관점에서 가장 중요한 변경점만 추려서 정리한다.


한눈에 보는 핵심 변경점

  • Spring Framework 7 / Jakarta EE 11 기반으로 전환
  • Java 25에 대한 1급 지원, 단 Java 17 호환은 유지
  • 거대한 auto-configure JAR을 작은 단위 모듈로 분해
  • JSpecify 기반 null 안전성을 표준으로 채택
  • API 버저닝 내장 지원 (@GetMapping(version = "1.0"))
  • 인터페이스로 HTTP 클라이언트를 만드는 HTTP Service Clients
  • Jackson 3 기본 채택 (패키지 경로 변경)
  • Gradle 9 빌드 지원
  • GraalVM 25+ 네이티브 이미지 요구사항 상향

출시 배경 — 왜 4.0인가

Spring Boot 3.x는 2022년 말 출시된 이후 약 3년 동안 안정적인 LTS 라인으로 쓰였다. 그동안 Java는 17 → 21 → 25로 두 번의 LTS를 거쳤고, Jakarta EE도 10에서 11로 올라갔다. 무엇보다 Spring Framework 7이 등장하면서, Boot 쪽도 그에 맞게 베이스라인을 끌어올릴 시점이 됐다.

Spring 팀이 이번 릴리즈에서 강조하는 키워드는 두 개다. 모듈화null 안전성. 둘 다 *"이미 동작하는 앱"* 보다는 *"앞으로 만들어질 앱"* 을 위한 변화에 가깝다. 즉, 4.0은 화려한 신기능이라기보다 앞으로 5년치 토대를 다시 까는 작업이라고 보는 편이 정확하다.


1. 코드베이스 모듈화 — 거대한 가방을 여러 개의 작은 가방으로

3.x 시절에는 spring-boot-autoconfigure라는 거대한 JAR 하나가 거의 모든 자동 설정을 들고 있었다. WebMVC만 쓰는 프로젝트에서도 LDAP, Neo4j, Quartz 같은 자동 설정 클래스가 클래스패스에 함께 끌려왔다.

Spring Boot 4.0은 이 구조를 깨고, 각 기술별로 작고 집중된 JAR로 쪼갰다. 예를 들어 spring-boot-starter-webmvc를 추가하면 WebMVC 관련 자동 설정만 따라온다. 그 결과 다음과 같은 효과가 있다.

  • 시작 시간 단축: 클래스패스 스캔 대상이 줄어든다
  • 메모리 사용 감소: 불필요한 자동 설정이 안 올라온다
  • 디버깅 편의성: 어디서 어떤 자동 설정이 들어왔는지 추적이 쉬워진다

다만 모듈이 잘게 쪼개진 만큼, starter POM을 쓰지 않고 직접 의존성을 관리하던 프로젝트는 의존성 누락 이슈가 발생할 수 있다. 마이그레이션 가이드에서도 이 부분을 가장 먼저 강조한다.


2. Java 25 1급 지원, Java 17 호환 유지

Spring Boot 4.0의 최소 요구 Java 버전은 여전히 Java 17이다. 다만 권장은 Java 25 LTS다.

Spring Boot 4.0 requires Java 17 or newer, with first-class support for Java 25.

여기서 "1급 지원(first-class support)"이 의미하는 바는, 단순히 Java 25에서 동작한다는 게 아니라 Virtual Threads, Pattern Matching, Sequenced Collections, 향상된 GC 같은 최신 JVM 기능을 프레임워크 차원에서 적극 활용한다는 뜻이다.

네이티브 이미지를 쓰려면 이야기가 좀 다르다. GraalVM 25 이상이 필요하다. 이전 GraalVM 23/24에서 빌드되던 네이티브 이미지가 그대로 빌드되지 않을 수 있으니, 네이티브를 쓰는 팀은 빌드 파이프라인을 먼저 점검해야 한다.


3. JSpecify로 표준화된 null 안전성

이번 릴리즈에서 가장 조용하지만 가장 영향력이 큰 변화다.

기존 Spring 코드에서 null 처리는 사실상 컨벤션에 의존했다. @Nullable 같은 애노테이션이 있긴 했지만, 어디 패키지의 어떤 애노테이션을 쓰느냐가 라이브러리마다 달랐다(Spring, JetBrains, Checker Framework, FindBugs…). IDE는 이걸 어찌어찌 통합해서 표시해줬지만, 일관성은 부족했다.

Spring Boot 4.0은 JSpecify를 표준 null 안전성 라이브러리로 채택했다. JSpecify는 Google, JetBrains, Spring 팀이 함께 합의한 일종의 표준 신호 체계다. 핵심 애노테이션은 다음과 같다.

  • @Nullable — 이 값은 null일 수 있다
  • @NonNull — 이 값은 절대 null이 아니다
  • @NullMarked — 이 패키지/클래스의 모든 참조는 기본 non-null이다

package-info.java@NullMarked를 한 번만 붙이면 패키지 안의 모든 참조 타입이 기본 non-null로 간주되고, null이 들어올 수 있는 곳만 @Nullable로 표시하면 된다. 코드 가독성이 명확해지고, IntelliJ나 NullAway 같은 정적 분석 도구가 빌드 단계에서 더 잘 잡아낸다.

// package-info.java
@NullMarked
package com.kraft.member;

import org.jspecify.annotations.NullMarked;
public Member findById(Long id) { ... }       // 절대 null 아님
public @Nullable Member findByEmail(String email) { ... }  // null 가능

기존 코드에 즉시 영향을 주진 않지만, 새로 작성하는 코드에는 처음부터 적용하는 게 좋다.


4. API 버저닝 — 이제 컨트롤러 한 줄로 처리

API 버저닝은 그동안 모든 팀이 각자의 방식으로 고생하던 영역이었다. URL 경로(/v1/...)에 박아 넣거나, 커스텀 헤더로 분기하거나, 미디어 타입으로 분기하거나. 어느 방식을 택하든 컨트롤러를 직접 갈라야 했고, 전략을 바꾸면 모든 컨트롤러를 다시 손대야 했다.

Spring Boot 4.0에서는 @RequestMapping 계열 애노테이션에 version 속성이 추가됐다.

@RestController
@RequestMapping("/api/posts")
public class PostController {

    @GetMapping(version = "1.0")
    public PostV1Response getPostsV1() { ... }

    @GetMapping(version = "2.0")
    public PostV2Response getPostsV2() { ... }
}

버전 분기 전략(URL, 헤더, 미디어 타입)은 설정에서 한 번만 정의하면 되고, 컨트롤러는 버전 번호만 신경 쓰면 된다. 전략을 나중에 바꿔도 컨트롤러 코드는 그대로 둘 수 있다는 점이 핵심이다.


5. HTTP Service Clients — 인터페이스만 선언하면 끝

외부 API를 호출할 때 RestTemplate이나 WebClient로 매번 코드를 짜는 대신, 인터페이스만 선언하고 구현체를 자동 생성하는 방식이 정식 자동 설정으로 들어왔다.

@HttpExchange(url = "https://api.example.com")
public interface WeatherClient {

    @GetExchange("/weather/{city}")
    WeatherResponse getWeather(@PathVariable String city);

    @PostExchange("/alerts")
    AlertResponse createAlert(@RequestBody AlertRequest request);
}

Feign이나 Retrofit을 써 본 사람이라면 친숙할 것이다. 차이는 Spring 자체에 통합됐다는 점이다. 별도 라이브러리 없이 @HttpExchange만 붙이면 Spring Boot가 알아서 구현체를 만들어 빈으로 등록한다. 4.x의 Spring Cloud Commons 5.0에서는 여기에 Circuit Breaker, 로드밸런싱(lb:// 스킴) 같은 기능까지 선언적으로 얹을 수 있다.

마이크로서비스 환경이 아니더라도, 외부 API를 호출하는 곳이 많은 프로젝트라면 코드량이 눈에 띄게 줄어든다.


6. Jackson 3 — 패키지 경로가 바뀐다

Spring Boot 4.0은 Jackson 3을 기본 JSON 라이브러리로 채택했다. 가장 눈에 띄는 변경은 패키지/그룹 ID다.

  • com.fasterxml.jackson.*tools.jackson.* 로 이동
  • 단, jackson-annotations 모듈은 호환성 때문에 com.fasterxml.jackson.core 그룹 ID와 com.fasterxml.jackson.annotation 패키지를 유지

직접 ObjectMapper를 import해서 쓰는 코드가 있다면 패키지 경로를 바꿔야 한다. 다만 Jackson 2를 요구하는 외부 라이브러리도 여전히 많기 때문에, Jackson 2와 3을 한 프로젝트에서 공존시킬 수 있도록 의존성 관리는 계속 제공된다.


그 외 주목할 변화

위에 적은 6가지 외에도 실무에서 한 번씩 만나게 되는 변경이 많다.

  • OpenTelemetry Starter 신설: spring-boot-starter-opentelemetry 추가만으로 OTLP 메트릭/트레이스를 내보낼 수 있다
  • Gradle 9 지원: Gradle 8.14 이상이면 둘 다 지원
  • Kotlin 2.2+ 요구: Kotlin 프로젝트는 빌드 환경부터 점검 필요
  • 클래식 uber-jar 로더 제거: 빌드 스크립트에서 관련 설정을 떼야 한다
  • Spring Retry 의존성 제거: 재시도 로직은 spring-core의 새 retry API로 이동
  • Testcontainers 모듈 prefix 정리: 모든 모듈이 testcontainers- 접두어로 통일
  • SSL 인증서 만료 모니터링 강화: expiringChains 항목 추가로 만료 임박 인증서를 health 응답에서 분리해 보여줌

3.x → 4.x 업그레이드, 무엇을 점검해야 하나

기존 프로젝트를 올리려면 다음 순서로 접근하는 게 안전하다.

  1. 3.5로 먼저 올린다: 3.x 안에서 deprecated 된 API를 모두 정리한 뒤 4.x로 점프
  2. Java 17 이상인지 확인: 11이나 8을 쓰고 있다면 자바 마이그레이션이 선행
  3. starter POM 사용 여부 점검: 직접 의존성 관리를 하고 있다면 누락 모듈 식별이 가장 먼저
  4. Jackson 사용처 점검: com.fasterxml.jackson.* 직접 import 여부, 커스텀 직렬화 코드 확인
  5. 네이티브 이미지 쓰는 경우 GraalVM 25로 업그레이드
  6. JSpecify 기반 정적 분석 도입 검토: 즉시 적용은 부담스러우면 신규 패키지부터

운영 중인 서비스를 무조건 빨리 올릴 이유는 없다. 3.x도 한동안 유지보수가 계속될 예정이고, 4.0의 진가는 신규 코드를 쓸 때 더 잘 드러난다.


마무리 — 4.0을 어떻게 받아들여야 할까

Spring Boot 4.0은 눈에 확 띄는 신기능 보다는 앞으로 5년의 토대를 다시 까는 릴리즈에 가깝다. 모듈화로 슬림해진 런타임, JSpecify로 표준화된 null 안전성, 인터페이스 기반 HTTP 클라이언트, 내장 API 버저닝 — 이 네 가지만으로도 신규 프로젝트라면 4.x로 시작할 명분이 충분하다.

반면 운영 중인 3.x 서비스는 서두를 필요가 없다. 3.5에서 deprecated 정리부터 차근차근 하면서, 분기점이 잡힐 때 옮기면 된다. 진짜로 챙겨야 할 건 새로 짜는 코드부터 4.x 스타일로 쓰는 것이다. JSpecify 애노테이션, 인터페이스 기반 HTTP 클라이언트, API 버저닝 attribute 같은 건 지금 손에 익혀두면 마이그레이션 시점에 부담이 훨씬 줄어든다.

Spring Boot 4.0은 이미 동작하는 앱을 깨러 온 게 아니라, 앞으로 만들 앱을 더 잘 만들게 하러 온 릴리즈다. 그 관점으로 보면 어디서부터 손을 댈지 답이 보인다.


참고 자료

  • Spring Boot 4.0 Release Notes (spring-projects/spring-boot Wiki)
  • Spring Boot 4.0 Migration Guide
  • Spring 공식 블로그 — Spring Boot 4.0.0 available now (2025.11.20)
  • JetBrains Blog — Spring Boot 4: Leaner, Safer Apps and a New Kotlin Baseline

#SpringBoot4 #SpringBoot #Java25 #JSpecify #APIVersioning #HTTPInterface #Jackson3 #SpringFramework7 #JakartaEE11 #백엔드 #Spring업그레이드 #자바개발


728x90
반응형
728x90
반응형

자바 프로젝트를 할 때 pom.xml과 build.gradle… 도대체 뭐가 더 좋은 걸까요?
지금부터 Maven과 Gradle의 개념, 차이, 실무 적용 팁까지 정리해드립니다!


🛠 Maven이란?

  • Apache Maven은 자바용 프로젝트 빌드 & 라이브러리 관리 도구입니다.
  • 기존에 쓰이던 Ant의 대안으로 만들어졌고, 지금도 많이 사용되고 있어요.
  • 오픈소스(아파치 라이선스)로 배포됩니다.

📌 Maven의 핵심은 POM!

<!-- pom.xml 예시 -->
<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>demo-app</artifactId>
  <version>1.0.0</version>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
  </dependencies>
</project>
 

💡 Maven 특징 요약

항목설명
🔗 POM 기반 Project Object Model (pom.xml) 중심 구조
📦 의존성 관리 자동으로 관련된 라이브러리도 같이 가져옴
🧱 표준화된 빌드 구조 설정이 정형화되어 있어 진입장벽 낮음
🧩 플러그인 중심 빌드 compile, test, package, install 등 명확
 

⚙ Gradle이란?

  • Gradle은 차세대 빌드 시스템으로, 빌드 속도가 빠르고 유연한 스크립트 작성이 강점이에요.
  • 특히 Android 앱 공식 빌드 도구로 사용되며, 최근에는 자바 서버에서도 많이 채택됩니다.
  • Groovy 또는 Kotlin DSL 기반으로 동작합니다.

🧠 Gradle은 이렇게 생겼어요

// build.gradle 예시
plugins {
    id 'java'
    id 'application'
}

group = 'com.example'
version = '1.0.0'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
}

💡 Gradle 특징 요약

항목설명
빠른 빌드 속도 캐시 및 병렬 빌드 지원
🧑‍💻 유연한 스크립트 기반 Groovy/Kotlin으로 빌드 로직 작성
📱 Android 필수 도구 Android Studio 기본 빌드 시스템
🧩 다양한 언어 지원 Java, C/C++, Python 등 다언어 빌드 가능
 

🔍 Maven vs Gradle 비교표

항목MavenGradle
설정 방식 XML (pom.xml) Groovy/Kotlin DSL
가독성 ❌ 길고 정형화됨 ✅ 간결하고 유연함
빌드 속도 느린 편 빠름 (캐시 활용)
멀티 모듈 설정 상속 기반 설정 주입 가능 → 더 유리함
대중성 기존 레거시/공공 시스템 다수 사용 최근 Spring, Android 중심 확산
학습 난이도 초보자에게 쉬움 유연하지만 초반 진입장벽 있음
 

🧑‍💻 그럼 어떤 걸 써야 할까?

상황추천
새 프로젝트 / Spring Boot Gradle 추천 (속도 + 유연함)
안드로이드 앱 개발 무조건 Gradle
공공기관 / 보수적 환경 Maven 유지보수 쉬움
기존 Maven 프로젝트 확장 그대로 Maven 사용 or Gradle로 전환 고려
멀티 모듈 + 빠른 빌드 원하는 경우 Gradle 확실히 유리함
 

✅ 마무리 요약

  • Maven은 표준적이고 안정적인 XML 기반 빌드 시스템
  • Gradle은 속도와 유연성 모두 잡은 차세대 빌드 도구
  • 실무에서는 Gradle이 점점 Maven을 대체하는 추세
728x90
반응형
728x90
반응형

자바 개발을 하다 보면 JAR, WAR, EAR 같은 단어를 많이 듣게 됩니다.
“이게 대체 뭐고 언제 뭘 써야 하지?”
아래 이미지와 함께 구조적 차이Spring Boot에서의 선택 기준을 쉽게 설명드릴게요.


📦 JAR / WAR / EAR 구조 한눈에 보기

위 그림을 보면 구조를 직관적으로 알 수 있어요:

  • JAR: 클래스 파일과 설정이 들어간 기본 단위
  • WAR: 웹 애플리케이션 배포용, WEB-INF, web.xml 포함
  • EAR: 여러 WAR + JAR 묶은 엔터프라이즈 통합 패키지

🔍 각 파일의 의미

✅ JAR (Java ARchive)

  • 자바 클래스와 메타정보를 하나로 압축한 파일
  • 애플리케이션이나 라이브러리를 배포할 때 사용
  • .class, META-INF/manifest.mf 포함

✅ WAR (Web Application Archive)

  • 웹 애플리케이션을 위한 구조
  • JSP, Servlet 기반 웹 프로젝트를 배포하는 데 사용
  • WEB-INF/web.xml, classes, lib 등 구조 고정

✅ EAR (Enterprise ARchive)

  • 기업용 대규모 시스템 통합 배포에 사용
  • 여러 WAR, JAR 모듈을 하나로 묶은 컨테이너
  • WebLogic, JBoss 같은 Java EE 서버 환경에 최적화

🚀 Spring Boot에서의 JAR vs WAR

항목                                          JAR (기본값)                                                             WAR
WAS 포함 ✅ 내장 Tomcat 내장 ❌ 외부 WAS 필요
실행 방식 java -jar로 바로 실행 Tomcat, WebLogic 등에서 배포
설정 편의성 간단한 구조, 빠른 실행 web.xml, 복잡한 디렉토리 구조
JSP 지원 ❌ JSP 미지원 (공식 비권장) ✅ JSP 사용 가능
활용 예시 REST API, 간단한 마이크로서비스 JSP/Servlet 중심 웹 프로젝트, 전통 웹앱

 

🧩 JSP + Spring Boot = WAR 필요?

Spring Boot에서 JSP를 사용하려면 아래 조건이 필요합니다:

  1. 프로젝트를 WAR로 패키징
  2. application.properties에 아래 설정 추가:
properties
복사편집
spring.mvc.view.prefix=/WEB-INF/views/ spring.mvc.view.suffix=.jsp
  1. JSP 파일은 src/main/webapp/WEB-INF/views/에 위치

📌 JAR로 배포할 경우 JSP는 작동하지 않음!
→ Thymeleaf, Mustache 등 템플릿 엔진 사용을 권장합니다.


✅ 정리 요약

구분                                                           JAR                                     WAR                                    EAR
내장 Tomcat ✅ 있음 ❌ 없음 ❌ 없음
실행 단독 실행 가능 WAS 필요 Java EE 서버 필요
JSP ❌ (제한적)
구조 단순 정형화 필요 매우 복잡
Spring Boot 기본
 

🏁 마무리

  • 개인 프로젝트, 마이크로서비스, REST API → JAR 추천
  • JSP, 레거시 웹앱 → WAR 필요
  • 대규모 엔터프라이즈 시스템 → EAR (하지만 요즘은 잘 안 씀)

Spring Boot는 기본적으로 JAR 중심 구조이며,
WAR는 외부 WAS와 JSP 기반 웹앱에 한정해서 사용하는 경우가 많습니다.

728x90
반응형

+ Recent posts