Spring Boot 3.0 무엇이 달라질까?
Spring Boot 3 (Spring Framework 6) 무엇이 달라질까?
지난 10월 20일 Spring Boot 3.0.0 RC1 가 릴리즈 되었습니다.
정식 버전 릴리즈는 11월 말 예정입니다.
"We are not expecting any more features to be added at this point, and we will only be making API changes if we find issues."
"현재로서는 더 이상 기능이 추가되지 않을 것이며 문제가 발견되는 경우에만 API를 변경할 것입니다."
많은 서버 개발자분들은 Spring Boot 3 에는 무엇이 추가되고 달라질지 궁금하실텐데요.
더 이상 기능이 추가되진 않을 것 같아 RC1 기준으로 새로운 내용들을 정리해 보았습니다.
Spring Boot 3 (Spring Framework 6) 는
✔ Java 17 이상을 지원합니다. (Kotlin 1.7+)
✔ Java EE를 jakarta EE 로 대체합니다 (javax.* 에서 jakarta.* 로 변경됩니다.)
✔ GraalVM 기반의 Spring Native가 3년간의 실험을 마치고 공식 지원을 시작합니다.
✔ HTTP/RSocket Interface Client를 제공합니다,
✔ Micrometer Observation API가 자동으로 구성되며, Observability 가 공식 지원을 시작합니다.
✔ HTTP API 에러 처리를 위한 RFC 7807 스펙을 지원합니다.
✔ 보안상 이슈로 /api/hello 와 /api/hello/ 는 더 이상 일치하지 않습니다.
✔ Logback 및 Log4j2 날짜 및 시간의 기본값이 ISO-8601 표준을 따릅니다.
✔ 사용되지 않는 (Deprecated) 모든 코드가 제거됩니다.
👉 Spring Framework 6.x 의 새로운 기능 더 보기
Spring Boot 3 으로 마이그레이션은
1. Java 17로 업그레이드 하세요.
2. Spring Boot 2.7.x 로 순차적으로 (2.5 -> 2.6 -> 2.7) 업그레이드 하세요.
3. Deprecated 코드를 찾아 (-Werror 옵션) 제거 하세요.
4. 레거시 application.properties 및 application.yaml 을 확인하세요. (use-legacy-processing)
5. (옵션) AntPathMatcher 를 사용중이라면 성능이 더 좋은 PathPatternParser으로 변경하세요.
6. 타사 프로젝트에서 Jakarta EE 9 를 호환하는 릴리즈가 있는지 확인하세요.
7. 타사 프로젝트에서 Spring Framework 6 을 호환하는지 확인하세요.
8. Spring Boot 3 으로 마이그레이션 하세요.
👉 Spring Boot 3 마이그레이션 전체 내용 더 보기
(참고) Spring Boot 2.7.x 는 2023년 11월까지 지원 예정입니다.
Q&A
*아래 내용은 여러 게시글들을 토대로 직접 작성한 내용입니다. 혹시 잘못된 부분이 있다면 댓글로 알려주세요.
✔ Java 17이 필수 조건인가요?
(한줄요약) 네 필수입니다.
작년 2021년 9월 SpringOne 에서 발표된 바와 같이 Spring Framework 6 는 Java 17를 최소 사양으로 계획하고 있었습니다. Java 17도 출시(2021.9.14) 된지 얼마 되지 않은 시기였기에 우려하는 목소리가 많았습니다. 1년여 지난 지금 많은 프로젝트에 채택되어 사용되고 있습니다만, 아직도 Java 11 이 대세이며, Java 8 도 많이 사용되고 있습니다. 개인적으로도 Java 17로 왜 업그레이드 해야하는가에 대한 질문을 받으면 바로 체감할 수 있는 수준에서 "새로 추가된 record class 가 좋아요." 하겠지만 코틀린을 사용하면 사실 크게 와 닿지 않기도 하고, 운영 측면의 리스크를 감안하여 java 17 로 업그레이드 할 만큼 큰 메리트가 없는 건 사실입니다.
하지만 잘 살펴보면 Java 11과 비교하여, GC 등 성능 개선도 있었고, 문자열, 리스트 등 API 인터페이스들도 더 다양하게 지원하고 있고, 타입 추론 키워드도 추가되고, switch 문도 확장 등 많은 개선들이 있었습니다.
Java 17을 고민 중이었다면, 이번 기회에 새로운 Spring Boot 3 (Spring Framework 6) 호환을 위하여서라도 업그레이드를 고려해보는 건 어떨까요?
✔ Java EE 패키지 네임스페이스가 도대체 왜 jakarta 로 변경되는 건가요?
(한줄요약) java 상표권 이슈로 변경되었습니다.
Java 개발자라면 한번 쯤 Java EE를 들어보셨을겁니다. Java EE에 대해서 좀 알고 가면 좋을 것 같은데요. EE는 Enterprise Edtion 의 약자로, 과거 썬 마이크로시스템즈가 분산 어플리케이션 개발을 위하 내세운 산업 표준입니다. 우리가 흔히 접해봤던 것으로는 Servlet, JSP, JDBC, JMX 등이 있습니다. 예를 들어, MySQL, Oracle, PostgreSQL 과 같이 다양한 Database 가 있는데 Java EE 호환성 스펙에 맞는 JDBC 드라이버를 사용하면, 큰 변경 없이 다른 Database 로 교체할 수 있는 것이죠.
하지만 썬-오라클 합병 이후에도 상업용 플랫폼이었던 Java EE는 오픈소스 생태계에 밀려 빠른 기술 트랜드를 따라가지 못하다가 2017년 비영리 단체인 이클립스 재단에 JavaEE 가 이관 되었습니다. 그리고 2019년 Java EE 8 과 완벽하게 호환되는 Jakarta EE 8 를 출시 했습니다. 이로써 기존 Java EE 는 벤더 중립적인 커뮤니티 기반의 프로세스를 가지게 되었습니다. 기존에 java 는 오라클이 상표권을 갖고 있었기 때문에 jakarta 로 이름이 변경되었습니다. 이후 네임스페이스 역시 상표권 이슈로 api 네임스페이스를 javax 에서 jakarta 로 변경하여 jakarta EE 9 가 2020년에 릴리즈되었습니다.
참고로 jakarta는 자바섬에서 가장 큰 도시이자 인도네이사의 수도인 Jakarta에서 따왔다고 합니다.
👉 Java EE에서 Jakarta EE로의 전환 (삼성 SDS 인사이트) 에서 관련 내용 더 보기
jakarka EE 적용으로 인해 namespace 이 변경되어서 Spring Boot 3 으로 마이그레이션 시 챙겨야 할 포인트들이 늘어나는데요. 일단은 기존 프로젝트에서 코드에서 javax.* 부분을 jakarta.* 으로 변경해야 합니다. 또한 타사 프로젝트나 라이브러리도 관련이 있다면 jakarta EE 9 이상을 호환하고 있는지 잘 살펴봐야 합니다. jakarta EE 9 채택으로 좋아진 점은 최신 웹 컨테이너 세대인 Tomcat 10, Jetty 11 과 호환 됩니다. 또한 호환성 문제로 제거되었던 EhCache 3 및 H2 Console 등 에 대한 지원이 복원됩니다.
✔ Spring Native 를 꼭 써야 하나요?
(한줄요약) 아직은 좀 더 지켜봐도 될 것 같습니다.
시스템이 점점 더 고도화되고, 특히 마이크로서비스 아키텍처를 많은 조직에도 도입하게 되면서 더 많은 리소스를 필요로 하게 되었습니다. 거기다가 Java + Spring Boot 를 사용하면 서버 실행 시간이 오래 걸릴 뿐만 아니라, 기본적으로 메모리 사용도 높은 편입니다. 이러한 문제를 해결하기 위한 솔루션으로 GraalVM 이 등장하였는데요. 이를 사용하게 되면 자바 프로젝트이지만 네이티브 바이너리로 만들어 실행 시간과 메모리 사용량을 획기적으로 줄여줍니다. Spring Native는 GraalVM Native Image 컴파일러를 이용하여 클라우드 환경에서 Native Binary 를 쉽게 만들 수 있게 합니다.
👉 GraalVM, Spring Native 맛보기 (NHN Cloud Meet) 에서 관련 내용 더 보기
이 때 알아 둘 개념이 두개 있는데요. JIT(Just in Time) Compile 과 AOT(Ahead of Time) Compile 입니다. 간단히 설명하자면 JIT Compile는 런타임에 Java 바이트 코드를 기계어로 변환하는 컴파일을 말하며, HotspotVM 의 기본설정입니다. AOT Compile은 GraalVM에서 사용되며, 빌드 타임에 Java 바이트 코드가 기계어로 컴파일 되는 방식을 말합니다. AOT Compile 의 결과물은 특정 플랫폼에 종속된 바이너리가 생성되어 매우 빠르게 실행됩니다. 또한 적은 오버헤드로 인해 더 적은 cpu와 메모리 자원을 사용하게 됩니다. 이러한 장점들로 인해 빠른 부팅과 보다 적은 리소스 사용이 요구되는 클라우드 환경에서 동작하는 애플리케이션에 적합하다는 평가를 받고 있습니다.
👉 Java에서의 AOT vs JIT 컴파일 (shirohoo 님 블로그) 에서 관련 내용 더 보기
Spring Native는 Spring Cloud 팀에서 3년 넘게 준비하고 이번 Spring Boot 3 부터 정식으로 도입됩니다. 하지만 GraalVM 을 사용하거나 적용해보신 분들은 아시겠지만 리플렉션 및 프록시에 대한 구성 필요 등등 아직 많은 제약 사항들로 있어 도입 시 예상 못한 어려움이 있을 수 있습니다. 또한 일부 개발자들은 GraalVM이 Java 의 미래인지에 대한 의구심을 갖고 있긴 합니다. 그럼에도 GraalVM의 이점이 분명하기에 앞으로도 더 관심이 높아질 것으로 보입니다. 도입을 고려하고 있다면 충분히 관련 개념을 익힌 뒤에 도입하는 것을 권장 드립니다.
👉 Spring Native 공식 문서에서 관련 내용 더 보기
✔ 그 외에도 클라우드 환경과 관련된 기능에는 어떤게 있나요?
서비스 인터페이스 선언만으로 Http Access 가 가능한 Http Interface Client 가 추가되었습니다. 기존에 OpenFeign 등을 써본 적이 있다면 익숙 할텐데요. RestClient 또는 WebClient 와 같은 클래스로 직접 구현하지 않더라도, 인터페이스만 선언하면 API 호출이 가능해집니다. 또한 RSocket 도 동일한 방식으로 RSocket interface를 지원합니다.
모니터링을 위한 메트릭에 대한 지원도 강화되었습니다. Micrometer Observation API 가 기본 설정되었으며, 메트릭, 로깅, 분산 추적 등의 기능을 제공하는 Observability 이 공식적으로 추가됩니다. Micrometer로 애플리케이션 메트릭을 효율적으로 기록하고, OpenZipkin 및 OpenTelemetry 와 같은 3rd-party 와의 통합이 견고해집니다.
✔ RFC 7807이 뭔가요?
RESTful API 개념을 잘 이해하고 쓰고 계신가요? GET, PUT, POST, PATCH, DELETE... 그리고 API 패턴 등등.. 그런데 에러가 났을 때 어떻게 처리 해야 하는지, 어떻게 처리해야 하는게 올바른 방법인지 깊은 고민은 별로 못했던 것 같습니다. RFC 7807은 이러한 API 에러 응답값에 대한 표준 스펙입니다. 예를들어, 403 권한 에러 일때의 응답은 content-type이 application/problem+json 이고, 발생 path, 에러정보, 에러 상세정보, 관련 문서링크, 그 외 참고 데이터들을 전달하도록 규정하고 있습니다. RFC 7807 문서에 예시까지 잘 나와 있어서 이해하는데는 어렵지 않을 것 같습니다.
이번 Spring Boot 3 에 RFC 7807이 적용된 Error Response 로 ProblemDetail 클래스가 추가 되었습니다. 이제 ControllerAdvice 설정 시 Response 를 ProblemDetail 으로 바꿔 표준을 적용해보면 어떨까요?
✔ Spring Boot 3 을 한번 써보려는데 어떻게 하면 되나요?
아직은 정식 버전이 출시되기 전이기 때문에 Maven 혹은 Gradle 설정에서 레파지토리에 https://repo.spring.io/milestone 마일스톤 URL 을 추가하여, 사용해 볼 수 있습니다. 간단하게는 https://start.spring.io 에서 새로운 프로젝트를 생성해볼 수 있습니다.
그리고 얼마 전 Spring Advocate인 Josh Long이 Spring Boot 3 영상을 하나 올렸는데요. 간단한 프로젝트를 통해 에러 처리, jakarta 관련 변경 점, Observation, Spring Native, Http Interface Client 등 새로운 기능들을 전부 경험해 볼 수 있는 컨텐츠로 구성되어 있으니, 관심있으신 분들은 아래 영상 참고해보세요.