
요약: Spring Boot 4.0이 2025년 11월 20일 정식 출시됐습니다. Spring Framework 7·Jakarta EE 11 기반의 세대교체 릴리스로, 마지막 3.x였던 3.5는 2026년 6월 오픈소스 지원이 끝났습니다. 이 글은 ①무엇이 바뀌었는지 핵심만, ②업그레이드 전 반드시 확인할 사전 점검, ③실제로 터지는 Breaking Change와 해결법, ④새로 생긴 기능(HTTP Service Clients·API 버저닝), ⑤단계별 마이그레이션 로드맵과 체크리스트를 실무 순서대로 정리했습니다.
Spring Boot를 쓰는 분이라면 요즘 "4.0으로 올려야 하나?"라는 고민 한 번쯤 해보셨을 겁니다. 2025년 11월, Spring Boot 4.0이 정식으로 나오면서 3.x 시대가 사실상 막을 내렸거든요. 그런데 "메이저 버전 올리면 뭐 하나는 꼭 터진다"는 게 경험칙이라, 무턱대고 올리기엔 불안한 것도 사실입니다. 오늘은 무엇이 바뀌었고, 무엇이 터지고, 어떤 순서로 안전하게 올리면 되는지를 실무 관점에서 차근차근 정리해 드리겠습니다.
스프링부트 4.0, 왜 지금 꼭 봐야 할까
가장 현실적인 이유부터 말씀드리면 지원 종료(EOL) 때문입니다. 마지막 3.x 마이너 버전이었던 Spring Boot 3.5는 2026년 6월 30일자로 오픈소스(OSS) 지원이 종료됐습니다. 즉 지금 3.5 이하를 쓰고 있다면, 앞으로 보안 패치를 무상으로 받지 못하는 상태라는 뜻입니다. (상용 연장 지원을 별도로 구매하는 선택지는 있지만, 대부분의 팀에게는 업그레이드가 정석입니다.)
두 번째 이유는 기술 세대교체입니다. Spring Boot 4.0은 아래 세 가지 위에 올라섰습니다.
- Spring Framework 7 — 코어 프레임워크의 메이저 업그레이드
- Jakarta EE 11 — Servlet 6.1 기반 (호환 컨테이너 필요)
- Java 17 최소 지원 유지 + Java 25 1급 지원 — JDK를 억지로 올리지 않아도 마이그레이션 가능
여기서 반가운 포인트가 하나 있습니다. Spring Boot 3으로 넘어올 때 가장 고통스러웠던 javax. → jakarta. 네임스페이스 대이동은 이미 3.x에서 끝난 일이라, 4.0에서는 그 작업을 다시 할 필요가 없습니다. 또 Java 최소 버전이 17로 유지되기 때문에, JDK를 꼭 25로 올려야만 4.0을 쓸 수 있는 건 아닙니다. 생각보다 진입 장벽이 낮다는 뜻이죠.

한눈에 보는 3.x → 4.0 핵심 변화
세부 내용을 보기 전에, 큰 그림을 표로 먼저 잡고 가겠습니다.
| 항목 | Spring Boot 3.x (3.5 기준) | Spring Boot 4.0 |
|---|---|---|
| 코어 프레임워크 | Spring Framework 6.2 | Spring Framework 7 |
| 플랫폼 | Jakarta EE 10 | Jakarta EE 11 (Servlet 6.1) |
| Java 최소/권장 | Java 17 이상 | Java 17 최소 · Java 25 1급 지원 |
| JSON 라이브러리 | Jackson 2 | Jackson 3 (기본) |
| 내장 서버 | Tomcat · Jetty · Undertow | Tomcat · Jetty (Undertow 제거) |
| 널 세이프티 | 스프링 자체 @Nullable |
JSpecify 표준 애너테이션 |
| 모듈 구조 | 비교적 큰 단위 jar | 잘게 쪼갠 다수 모듈 |
| 빌드 도구 | Gradle 7.x~ / Maven | Gradle 8.14 이상 권장 |
한 줄 요약: "터지는 건 주로 Jackson·제거된 서버·빌드 설정, 좋아지는 건 선언형 HTTP 클라이언트·API 버저닝" 입니다.
먼저 확인하세요 — 업그레이드 전 사전 점검
메이저 업그레이드는 "일단 버전만 올리고 빌드 돌려본다"가 제일 위험합니다. 올리기 전에 다음 네 가지를 먼저 점검하세요.
- JDK 버전 — Java 17 이상인지 확인합니다. 17이면 그대로 가도 되고, 이왕이면 21 또는 25 LTS 계열로 함께 정비하면 장기적으로 유리합니다.
- 빌드 도구 버전 — Gradle은 8.14 이상(가능하면 9.x)으로 먼저 올려두세요. 빌드 도구가 낮으면 4.0 의존성 해석 단계에서 막힙니다.
- 의존성 지도 그리기 — 내 프로젝트가 Jackson을 직접 다루는 코드(커스텀 Serializer/Deserializer,
ObjectMapper직접 설정 등)와 내장 서버로 Undertow를 쓰는지를 먼저 찾아둡니다. 이 둘이 4.0에서 가장 손이 많이 가는 지점입니다. - 테스트 커버리지 확인 — 마이그레이션의 안전벨트는 결국 테스트입니다. 핵심 비즈니스 로직과 API 응답(특히 날짜·JSON 포맷)에 대한 테스트가 있는지 점검하세요.
💡 팁: 가능하면 3.x의 마지막 버전(3.5.x)으로 먼저 올린 뒤 4.0으로 넘어가세요. 한 번에 두 단계를 건너뛰면 어디서 깨졌는지 원인 추적이 어려워집니다. "3.3 → 3.5 → 4.0" 처럼 계단식으로 올리는 게 디버깅이 훨씬 수월합니다.

실제로 터지는 것들 — Breaking Changes
이제 핵심입니다. 4.0에서 빌드가 실패하거나 동작이 달라지는 대표적인 변경점을 하나씩 보겠습니다.
① Jackson 3가 기본 — JSON 처리의 가장 큰 변수
Spring Boot 4.0부터 JSON 직렬화 기본 라이브러리가 Jackson 3로 바뀌었습니다. Jackson 3는 2의 단순 업그레이드가 아니라 별개의 메이저라, 다음이 함께 달라집니다.
- 패키지·그룹 ID 변경 — 기존
com.fasterxml.jackson계열 패키지·그룹 ID가tools.jackson으로 바뀌어, Jackson 내부를 직접 import 하던 코드는 수정이 필요합니다. - 날짜 기본 포맷 변경 — 날짜·시간이 기본적으로 ISO-8601 문자열로 직렬화됩니다. 예전처럼 숫자 타임스탬프를 기대하던 클라이언트가 있다면 API 응답이 달라져 깨질 수 있습니다.
- 설정 모델 변경 —
ObjectMapper설정 방식이 불변(immutable) 모델 쪽으로 정리됐습니다.
대응: API 응답 JSON의 날짜 포맷을 테스트로 고정해 두고, 커스텀 Jackson 설정이 있다면 가장 먼저 점검하세요. JSON을 직접 건드리지 않고 스프링에 맡겨 온 프로젝트라면 영향이 크지 않습니다.
② 내장 서버 Undertow 제거, OkHttp3 지원 제거
Jakarta EE 11의 Servlet 6.1을 Undertow가 아직 구현하지 않아, Undertow는 내장 서버 선택지에서 완전히 빠졌습니다. spring-boot-starter-undertow를 쓰고 있었다면 애플리케이션이 시작조차 되지 않습니다.
대응: 내장 서버를 Tomcat(기본) 또는 Jetty로 교체하세요. 또한 HTTP 클라이언트로 OkHttp3 연동을 쓰던 부분도 지원이 빠졌으니 대체가 필요합니다.
③ 모듈 세분화 — "스타터는 그대로, 세부 모듈은 쪼개짐"
4.0은 내부 모듈을 잘게 나눴습니다. 기능별로 jar가 작아져 꼭 필요한 것만 담을 수 있다는 장점이 있지만, 특정 세부 모듈을 직접 의존하고 있었다면 좌표(artifact 이름)가 바뀌어 수정이 필요할 수 있습니다. 반대로 spring-boot-starter-* 같은 스타터 단위로 의존해 온 프로젝트라면 대부분 그대로 넘어갑니다.
④ JSpecify 기반 널 세이프티
스프링 자체 애너테이션이던 org.springframework.lang.@Nullable, @NonNullApi 등이 업계 표준인 JSpecify 애너테이션으로 교체됐습니다. 코틀린을 쓰거나 정적 분석 도구(예: NullAway)를 돌리는 팀은 null 관련 경고가 더 정밀하게 잡히는데, 이게 오히려 숨어 있던 null 버그를 드러내 컴파일/분석 단계에서 막아주는 긍정적 효과가 큽니다.
그 밖에도 AOP 스타터 이름 변경, JUnit 4 기본 제외(JUnit 5로 전환), Gradle 최소 버전 상향 등 자잘한 변경이 많습니다. 공식 마이그레이션 가이드와 릴리스 노트를 함께 참고하시길 권합니다.

새로 생긴 무기 — New Features
바뀌는 것만 있으면 억울하죠. 4.0에서 새로 생긴, 실무에서 바로 반가운 기능 두 가지입니다.
HTTP Service Clients — 선언형 REST 호출
예전엔 외부 API를 호출할 때 RestTemplate이나 WebClient로 요청을 일일이 조립해야 했습니다. 4.0에서는 인터페이스에 애너테이션만 선언하면 구현체를 자동 생성해 주는 선언형 HTTP 클라이언트가 1급 기능으로 들어왔습니다. (Feign을 써본 분이라면 "그 느낌"이 바로 떠오르실 겁니다.)
@HttpExchange("/api/users")
public interface UserClient {
@GetExchange("/{id}")
User findById(@PathVariable Long id);
}
이렇게 선언만 해두면 실제 호출 코드를 직접 짜지 않아도 됩니다. 반복되던 보일러플레이트가 눈에 띄게 줄어듭니다. 테스트를 위한 RestTestClient도 함께 다듬어졌습니다.
API 버저닝 — 애너테이션으로 버전 라우팅
이제 별도 필터나 커스텀 로직 없이, 애너테이션으로 API 버전별 라우팅을 선언할 수 있습니다.
@GetMapping(value = "/users", version = "1.1+")
public List<User> listV11() { ... }
version = "1.1+"처럼 "1.1 이상" 같은 범위 매칭도 지원해서, API를 점진적으로 진화시킬 때 버전 관리가 한결 깔끔해집니다.
단계별 마이그레이션 로드맵
위 내용을 실제 작업 순서로 정리하면 이렇습니다.
- 백업·브랜치 분리 — 반드시 별도 브랜치에서 작업합니다.
- 3.5.x로 먼저 올리기 — 2단계 점프를 피해 원인 추적을 쉽게 만듭니다.
- 빌드 도구·JDK 정비 — Gradle 8.14+, Java 17 이상 확인.
- 버전 교체 — Spring Boot 버전을 4.0으로 올리고 BOM이 관리하는 의존성에 맡깁니다.
- 컴파일 에러부터 잡기 — Undertow 제거, 바뀐 모듈 좌표, Jackson import 등 "빌드가 안 되는" 것부터 해결.
- 런타임·동작 검증 — 서버 기동, JSON 날짜 포맷, 보안 설정 기본값 변화 등을 테스트로 확인.
- 새 기능 선택 도입 — 급하지 않다면 마이그레이션이 안정된 뒤 HTTP Service Clients·API 버저닝을 천천히 적용.
핵심 원칙: "기능 추가와 버전 업그레이드를 섞지 마세요." 업그레이드 PR에서는 오직 올리는 것만, 새 기능 적용은 그다음 PR에서. 문제가 터졌을 때 원인을 분리하기 위해서입니다.
마이그레이션 체크리스트 (저장용)
- [ ] JDK 17 이상 확인 (가능하면 21/25 LTS 정비)
- [ ] Gradle 8.14 이상으로 빌드 도구 업그레이드
- [ ] 3.5.x로 선행 업그레이드 후 4.0 진행
- [ ] Undertow 사용 여부 점검 → Tomcat/Jetty로 교체
- [ ] Jackson 직접 설정·커스텀 (역)직렬화 코드 점검
- [ ] API 응답 날짜 포맷(ISO-8601) 테스트로 고정
- [ ] 직접 의존하던 세부 모듈 좌표 변경 확인
- [ ] JUnit 4 잔재 → JUnit 5 전환
- [ ] 전체 테스트 통과 후 운영 반영
자주 묻는 질문 (FAQ)
Q. 꼭 지금 올려야 하나요? A. 3.5의 오픈소스 지원이 2026년 6월에 끝났기 때문에, 보안 패치를 무상으로 받으려면 4.0으로 올리는 것이 맞습니다. 다만 운영 중인 서비스라면 충분한 테스트 기간을 두고 계획적으로 진행하세요.
Q. Java를 25로 꼭 올려야 하나요? A. 아닙니다. 4.0은 Java 17 최소 지원을 유지합니다. 25는 "1급으로 지원"되는 것이고 필수는 아닙니다. JDK 교체 없이도 마이그레이션 가능합니다.
Q. 3에서 4로 넘어갈 때 javax → jakarta 작업을 또 해야 하나요? A. 아니요. 그 네임스페이스 대이동은 Spring Boot 3에서 이미 끝난 작업이라, 3.x에서 4.0으로 넘어올 때는 반복하지 않습니다.
Q. 가장 많이 터지는 지점은 어디인가요? A. 경험적으로 ① Jackson(JSON 날짜·커스텀 설정), ② 제거된 Undertow, ③ 빌드 도구 버전 이 세 가지가 가장 흔한 트러블입니다. 이 셋만 먼저 정리해도 절반은 해결됩니다.
마무리
Spring Boot 4.0은 "javax → jakarta" 때처럼 전면적인 코드 대이동을 요구하지는 않습니다. 대신 Jackson 3·제거된 서버·빌드 설정이라는 몇 개의 분명한 지점에 손이 갑니다. 반대로 HTTP Service Clients와 API 버저닝 같은 기능은 한 번 익히면 생산성이 눈에 띄게 올라가죠. 오늘 정리한 체크리스트대로 계단식으로, 테스트를 안전벨트 삼아 올리면 생각보다 매끄럽게 넘어갈 수 있습니다.
함께 보면 좋은 글: Spring Boot 예외 처리(@ControllerAdvice), Spring Boot 파일 업로드, JPA 연관관계와 N+1 문제 해결 — 4.0 환경에서도 그대로 통하는 실무 상록 주제들입니다. (※ 내부링크는 쿤즈랜드 Spring Boot 클러스터 기존 글과 연결)
이 글의 버전·날짜·사양 정보는 2026년 10월 기준 Spring 공식 발표 및 릴리스 자료를 바탕으로 작성했습니다. 세부 Breaking Change 전체 목록은 Spring Boot 4.0 공식 마이그레이션 가이드와 Spring Boot 4.0 릴리스 노트를 함께 확인하세요.
'쿤즈 Dev > Spring Boot' 카테고리의 다른 글
| 스프링 면접 질문 완전정복 ① — 코어 & AOP 10선 (순환참조·BeanPostProcessor·AOP 프록시 한 방 정리) (0) | 2026.10.23 |
|---|---|
| [Spring Boot] 롬복(Lombok)과 Mybatis 사용시 IndexOutOfBoundsException 발생 그리고 해결 방법 (0) | 2023.08.09 |
| [Spring Boot] Swagger 3.0 적용하기 (0) | 2023.07.25 |
| [Spring Boot] 앱 배포시 profile 설정 방법 (0) | 2023.01.30 |
| [Spring Boot] 엔티티에서 Setter 사용에 대한 생각 (1) | 2023.01.08 |
댓글