2018년 Spring 5.x.x 버전 릴리즈 되면서, 스프링 모듈 중 하나인 Webflux가 수많은 관심을 받았는데요.
벌써 4년이 훌쩍 넘어 Spring 6. 메이저 버전 업데이트가 점점 다가오고있습니다.
Springboot 3.0 (GA)의 예정 출시일은 2022년 10월 중입니다.
4년만의 메이저 업데이트에서는 어떤것이 반영될 예정인지 현재 SNAPSHOT Milestone 4 버전 릴리즈가 나온 시점에서 정리해보려고 합니다. 개선이나, 종속 변경보다는 실제 Spring 어플리케이션을 운영중인 상황에서 다소 주목해야할 부분들을 집어 왔습니다.
혹여나 제가 틀렸거나 잘못 해석한 부분이 있다면 댓글 부탁드리겠습니다.
가장 관심이 많을 부분이라고 생각되는데요,
SpringBoot 3.0 Release에서는 기존에 2.3.x 대에서 Java 8-17 을 그리고, Jakarta EE 7-8을 지원하였지만 이제는 최소 지원이 아래와 같아집니다.
기존에 Spring-Native 프로젝트에서 Native를 지원하기위해 3년이 넘는 시간동안 실험해왔던 관련 모듈들을 이제 따로 import하지 않고 기본 기능으로서 사용할 수 있게 되었습니다.
GraalVM Native Image는 Java 코드를 네이티브 이미지라고 하는 독립 실행형 실행 파일로 GraalVM을 통해 미리 컴파일하는 기술 입니다. 그 과정에서 AOT라는 정적 분석이 사전에 필요합니다. 이렇게 만들어진 네이티브 이미지는 JVM 에서 실행되지 않지만, 애플리케이션 클래스, 관련 종속성 클래스들, 런타임 라이브러리 클래스들 및 JDK의 정적으로 연결된 네이티브 코드가 포함되게 됩니다.
네이티브 이미지는 JVM에서 실행되지 않지만 Substrate VM(GraalVM 내부 프로젝트 이름 중 하나, 메모리 관리,스레드 스케줄링 등과 같은 런타임 필수 구성 요소를 포함하는 VM) 이라고 하는 가벼운 런타임 시스템을 이용합니다. 그렇기 때문에 네이티브 이미지는 JVM에 비해 시작 시간이 더 빠르고 런타임 메모리 오버헤드가 더 낮습니다.
AOT(Ahead-Of-Time) 엔진 지원
애플리케이션을 변환 및 최적화하고 필요한 GraalVM 기본 구성을 생성하기 위해 빌드 시 Spring 애플리케이션에 대한 심층 분석을 수행하는 AOT 엔진을 지원합니다.
AOT 엔진은 최적화된 애플리케이션 컨텍스트와 애플리케이션을 위해 특별히 제작된 Spring Factory를 생성하기 위해 빌드 시 조건을 평가하는 형태로 작동됩니다. 대표적인 장점으로는
AOT 엔진은 식별된 Bean, Spring 프로그래밍 모델에 대한 지식, Spring Native와 번들로 제공되거나 애플리케이션 자체에서 제공되는 네이티브 힌트를 기반으로 실행할 애플리케이션을 네이티브 실행 파일로 실행하는 데 필요한 네이티브 구성을 추론하는 정적분석을 수행합니다.
이유는 매트릭, 트레이싱 통합 과정중에서 각 매트릭과 통합에 관여하는 구체적 제품들이 더 중요하기 때문이라 하는데, 자세한 내용은 위 티켓에서 보실 수 있습니다.
bootjar, bootRun, bootWar는 이제 메인 소스의 출력에서 메인 클래스 이름을 확인하고 사용합니다.
직접 주입하던 방식에서 다른 메인클래스를 선언하여 의도하지 않은 동작을 만들 수 있었던 작은 위험 요소가 제거됩니다.
메인 소스 셋 외부의 기본 클래스에 의존하는 경우 아래와 같이 DSL 의 mainClass속성을 사용하여 명시적으로 기본 클래스 이름을 구성하도록 Gradle 구성을 업데이트하면 됩니다.
springBoot {
mainClass = "com.example.Application"
}
Logback 및 Log4j2의 default 로그 메시지 Datetime Format이 ISO-8601 표준에 맞게 변경 됩니다.
yyyy-MM-dd'T’HH:mm:ss.SSSXXX
공백 문자 대신'T’ 문자를 사용하여 날짜와 시간을 구분하고
끝에 표준 시간대 오프셋이 추가됩니다. logging.pattern.dateformat 프로퍼티를 수정하면, 기존 format으로 변경할 수 있습니다.
Spring Apache Kafka 에서 비동기 ACK를 활성화하기 위한 새 configuration이 지원됩니다.
spring.kafka.listener.async-acksKafka
비동기 ack를 활성화하려면 위 프로퍼티를 true로 설정합니다.
(이 속성은 spring.kafka.listener.async-mode가 manual또는 manual-immediate 으로 설정되었을 때만 작동합니다)
@ConfigurationProperties를 사용할 때 @ConstructorBinding 을 추가했었는데요, 이제는 args와 함께 선언된 단일 생성자가 있을때는 @ConstructorBinding 명시 할 필요가 없어집니다.
다만 만약 둘 이상의 생성자가 있는 경우에는 @ConstructorBinding 통해 바인딩에 필요한 생성자를 Spring에게 명시적으로 알려 주어야합니다.
그리고 @ConfigurationProperties를 사용하지 않고 바로 생성자에 주입은 @Autowired를 추가해야합니다.
아마 대부분 단일생성자로 사용하실테니 @ConfigurationProperties만 선언하고 사용하는 형태로 제거가 가능해질 것 같네요
기존에 아래와 같이 컨트롤러 선언시
@RestController
class TestController {
@GetMapping("/some/greeting")
fun greeting(): String {
return "greeting"
}
}
'/some/greeting'
'/some/greeting/'
후행 슬래시 존재 여부 상관없이 둘 다 greeting()으로 핸들링 될 수 있었습니다.
바로 핸들러매핑 과정에서 TrailingSlashMatch 라는 configuration의 값에 따라 설정해줄 수 있었기 때문인데요. 후행 슬래시를 사용할 수 있게 했던 setUseTrailingSlashMatch는 프록시, 서블릿/웹 필터 또는 컨트롤러를 통한 명시적 리디렉션 구성을 위해 6.0부터 더 이상 사용되지 않습니다. 그래서 이제는 후행 슬래시가 존재하는 '/some/greeting/' 요청과는 일치하지 않게 됩니다.
6.1으로 변경되면서 application의 마이그레이션은 신경쓸게 몇 가지 없지만 이전부터 hibernate 6.0 을 기용하기 시작하면서 Java EE 기반의 JavaPersistence 에서 -> Jakarta EE의 Jakrta Persistence로 변경됨에 따라 버전이 꽤 뒤쳐져있는 상태로 운영하고 있는 분들에게는 Jakarta EE 기반 Persistence로의 마이그레이션이 필요하다는 점이 더 중요할 것 같습니다.
Elasticsearch’s high-level REST client에 대한 지원이 중단되고, 대신 ElasticSearch의 새로운 Java Client에 대한 AutoConfiguration이 도입됩니다.
따라서 high-level REST client 위에 구축된 Spring-Data-ElasticSearch의 템플릿에 대한 지원이 제거되었으며, Java Client 기반으로 하는 신규 템플릿에 대한 AutoConfiguration도 도입되었습니다.
참고 - Spring 6.0 SNAPSHOP 공식 도큐먼트 ElasticSearch 파트
Flyway의 9.0 릴리즈 노트는 아래에서 보실 수 있습니다.
참고 - Flyway Release Note # 9.0.0
YamlJsonParserSnakeYAML의 JSON 구문 분석이 다른 구문 분석기 구현과 일치하지 않는 부분이 있어 제거되었다고 합니다.
혹시나 직접 사용 하는 경우 다른 구현 YamlJsonParser중 하나로 마이그레이션이 필요합니다.
Multiple batch jobs를 실행하는 것이 더 이상 지원되지 않습니다. Autoconfiguration에서 단일 작업만을 감지하면 시작 시 바로 실행되며, 컨텍스트에 여러 job이 있는 경우 시작 시 실행할 jobName을 spring.batch.job.name 속성을 사용하여 제공해야만 합니다.
spring.session.store-type 프로퍼티에 대한 직접 설정이 지원되지 않고, 둘 이상의 세션스토리지 구현체가 있을때는 앞으로는 아래와 같이 고정된 순서에 따라서 세션 스토리지 구현체를 결정합니다.
1순위. Redis
2순위. JDBC
3순위. Hazelcast
4순위. MongoDB
Redis, JDBC, Hazelcast 및 MongoDB를 사용할 수 없는 경우 SessionRepository에 대한 Configure를 하지 않습니다
Reactive webSession에서는 별도로 아래와 같은 우선순위를 가집니다.
1순위. Redis
2순위. MongoDB
3순위. Redis 또는 MongoDB를 사용할 수 없을 때 ReactiveSessionRepository에 대한 Configure를 하지 않습니다.
AuthenticationManagerResolver가 있는 경우 ReactiveUserDetailsService는 더 이상 자동으로 구성되지 않습니다.
AuthenticationManager Resolver가 있음에도 불구하고 ReactiveUserDetailService 사용하는 경우 자체적으로 ReactiveUserDetailServiceBean에 대한 정의가 필요합니다
안녕하세요, 글 잘 읽었습니다. 혹시 "@ConfigurationProperties를 사용할 때 @ConfigurationBinding 을 추가했었는데요, 이제는 args와 함께 선언된 단일 생성자가 있을때는 @ConfigurationBinding을 명시 할 필요가 없어집니다." 이 부분에 @ConfigurationProperties를 사용할 때 "@ConstructorBinding"을 추가..., "@ConstructorBinding"을 명시할 필요가 없어집니다. 로 수정되어야 하는 게 아닐까 해서 댓글 납깁니다..!
잘봤습니다.