Spring Boot 2.x’ten 3.x’e Geçiş Rehberi: Yenilikler, Avantajlar ve Dönüşüm

Gokhan Konuk
Akbank Teknoloji
Published in
5 min readMar 1, 2024

--

Bu yazımızda, Akbank Teknoloji olarak alt yapılarımızda kullandığımız Spring Boot framework’ü için Spring Boot 2.x’ten 3.x’e geçişin kod ve konfigurasyon açısından nasıl gerçekleştirileceğini anlatacağız. Ayrıca, bu geçişin getirdiği yenilikler, avantajlar ve dönüşümleri adım adım hep birlikte inceleyeceğiz.

Spring Boot, Java tabanlı web uygulamaları ve mikroservisler oluşturmak için popüler bir framework’tür. Her yazılımda olduğu gibi, en son güncelleme ve sürümlere ayak uydurmak, uygulamanızın güvenli, verimli, en son özellikler ve işlevlerle güncel kalmasını sağlamak için hayati önem taşır.

Neden Geçiş Yapmalıyız?

Kazançlar

  1. Java Sürümü ve Performans: Spring Boot 3.0, Java 17 gibi daha yeni sürümlerle uyumlu, bu da gelişmiş bellek yönetimi ve genel performans iyileştirmeleri anlamına gelir.
  2. Garbage Collection Algoritmaları: Yeni Java sürümleri, Z Garbage Collector gibi düşük gecikme süreli GC algoritmaları ile uygulamanın daha hızlı çalışmasına olanak tanır.
  3. JIT Derleyici İyileştirmeleri: Yeni Java sürümleri, Just-In-Time (JIT) derleyici iyileştirmeleri sunar. Bu, uygulama kodunun daha hızlı bir şekilde derlenmesini ve çalıştırılmasını sağlar, bu da performansa olumlu katkıda bulunur.
  4. Modülerlik (JPMS): Java Platform Module System, uygulamanın daha küçük ve hafif parçalara bölünmesine yardımcı olarak performansı artırır.
  5. Java Flight Recorder (JFR): Yeni Java sürümleri, geliştirme ve hata ayıklama için Java Flight Recorder gibi araçları içerir. Bu, uygulamanızın performansını izlemeyi ve hataları daha hızlı tespit etmeyi kolaylaştırır.
  6. Yeni Dil Özellikleri: Java 8'den sonraki sürümler, yeni dil özellikleri ekler. Bu, kodun daha açıklayıcı ve verimli olmasını sağlar.
  7. Mevcut Tech Stack için İyileştirmeler: JMS (Java Message Service), Kafka, Feign, vb..
  8. Spring Framework 6.0 Entegrasyonu: Daha modern API’ler, gelişmiş güvenlik özellikleri ve performans iyileştirmeleri sunar. Ve daha bir çok konularda kazançlar sağlar; Yeni Java sürümü desteği, Modüler Yapı, Reaktif Programlama Desteği, Geliştirilmiş Güvenlik Özellikleri, Daha Hızlı Initializer.

Maliyetler

  1. Bağımlılık Güncellemesi: Spring Boot 3.0'a geçmek, mevcut bağımlılıkların uyumluluğunu kontrol etmeyi ve gerektiğinde güncellemeyi gerektirir.
  2. Test ve Doğrulama Süreci: Geçişin başarılı olması için kapsamlı testler yapılmalıdır.
  3. IDE Güncellemesi: Kod geliştirmek için kullanılan IDE (Eclipse, IntelliJ, vs.) versiyonlarının güncel olması gerekmektedir.

Geçiş Planı: İki Aşamada Başarıyla Geçin

  1. Java Versiyonunu Güncelleme: Spring Boot 3'e geçiş için öncelikle Java versiyonunun 17 olması gerekmektedir.
  2. Çekirdek Değişiklikler: Yapılacak değişiklikleri şu başlıklar altında ele alabiliriz:
  • Configuration Properties: Bazı property key’ler değiştirildi.
1. [spring.redis to spring.data.redis] 
2. [spring.jpa.hibernate.use-new-id-generator is removed]
3. [server.max.http.header.size to server.max-http-request-header-size]
  • Jakarta EE 10:
1.Jakarta EE 10 yeni versiyonunda, Spring Boot 3 ilişkili dependency'leri spring-boot-starter dışından yönetiyorsak, update gerektiriyor.
a. Servlet specification updated to version 6.0
b. JPA specification updated to version 3.1

2.Ayrıca Jakarta EE, packages uzantılarında "javax" yerine "jakarta" kullanıyor, update sonrası import'ları da düzenlemek gerekiyor.
  • Hibernate: Eğer spring-boot-starter dışından yönetiyorsak, versiyonunun güncellenmesi gerekiyor.
  • Diğer Değişiklikler: Ayrıca bu yeni versiyonda, core seviyede bir çok önemli değişiklik mevcut.
1. Image banner desteği kaldırıldı. custom banner için sadece banner.txt geçerli.
2. Logging date formatı değişti, Logback ve Log4J2 için default : yyyy-MM-dd'T'HH:mm:ss.SSSXXX
a) Eğer eski default log format'ı kullanmak istersek, application.yaml içerisinde "logging.pattern.dateformat" property'sine setlemek gerekir.
3) @ConfigurationProperties class'larında, type level olarak @ConstructorBinding ihtiyacı yok, constructor level olarak ihtiyaç olabilir. Fakat class birden fazla constructor'a sahipse, property binding için kullanılacak olana @ConstructorBinding eklemeliyiz.

3. Web Uygulama Değişiklikleri: Web uygulaması düzeyindeki önemli değişikliklere odaklanarak geçiş sürecini başarılı kılabiliriz.

  • Trailing Slash Matching Configuration:
1. Spring Boot yeni release'de, rest endpoint url sonundaki "/" slash'i default olarak match etmeyecek şekilde configure edildi. Http 404 hatası verir.
2. Bunun için yeni bir configuration (WebMvcConfigurer or WebFluxConfigurer) class'ı implement edip, "useTrailingSlashMatch" değerini true olarak setlemek gerekir.
  • Response Header Size:
1. Http Header size property değişti demiştik, bu sadece request header size'ı kontrol eder. [server.max.http.header.size has moved to server.max-http-request-header-size]
2. Response header'a limit koymak için yeni bir bean tanımlanıyor.

@Configuration
public class ServerConfiguration implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
@Override
public void customize(TomcatServletWebServerFactory factory) {
factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
@Override
public void customize(Connector connector) {
connector.setProperty("maxHttpResponseHeaderSize", "100000");
}
});
}
}

-Tomcat: TomcatServletWebServerFactory
-Jetty: JettyServletWebServerFactory
-Not: Diğer embedded web container'ları bu özelliği desteklemiyor.
  • Diğer Değişiklikler:
1. Bu yeni release'de web application seviyesinde önemli değişiklikler var.
2. SmartLifecycle kontrollü kapatma aşamaları güncellendi. Spring "SmartLifecycle.DEFAULT_PHASE - 2048" bu seviyede kontrollü kapatmayı başlatıyor ve web sunucusunu "SmartLifecycle.DEFAULT_PHASE - 1024" seviyesinde durduruyor.
3. RestTemplate için HttpClient upgrade edildi: RestTemplate updates its version of Apache HttpClient5

4. Actuator Değişiklikleri: Actuator modülündeki önemli değişikliklere göz atalım ve bu değişikliklere nasıl uyum sağlanabileceğini anlayalım.

  • Actuator Endpoints Sanitization:
1. Önceki versiyonda Spring Framework endpoint içerisindeki /env ve /configprops key'lerinin değerlerini otomatik olarak masklıyordu. Bu yeni versiyonda, default olarak daha secure olmak için yaklaşımı değiştirmiş.
2. Bu configuration'ları property'ler ile değiştirebiliyorsunuz.
a. management.endpoint.env.show-values (for the /env endpoint)
b. management.endpoint.configprops.show-values (for the /configprops endpoint)
c. 3 farklı değer mevcut: NEVER, ALWAYS, WHEN_AUTHORIZED
  • Diğer Değişiklikler:
1. Jmx Endpoint Exposure: JMX sadece endpoint sağlığını kontrol eder. management.endpoints.jmx.exposure.include ve management.endpoints.jmx.exposure.exclude property'leri kullanılarak customize edilebilir.
2. httptrace endpoint renamed: /httptrace to /httpexchanges
3. Actuator endpoint için response'ları seriliaze eden ayrı bir ObjectMapper instance'ı var. Bu özelliği false yaparak değiştirebiliyoruz: management.endpoints.jackson.isolated-object-mapper: false

5. Spring Security: Güvenlik konusunda dikkat edilmesi gereken noktalara odaklanarak geçişinizi güvenli bir şekilde gerçekleştirin.

1. "Spring Boot 3" sadece "Spring Security 6" ile uyumludur.
2. "Spring Boot 3" upgrade edilmeden önce "Spring Boot 2.7" için "Spring Security 5.8" e upgrade edilmeli.
3. Sonrasında Spring Security 6 ve Spring Boot 3 upgrade işlemi yapılabilir.
4. Bir kaç önemli değişiklik bildiridi bu versiyonda:
a. ReactiveUserDetailsService artık otomatik olarak configure edilmiyor.
b. SAML2 Relying Party Configuration:
1) Spring Boot artık buradaki property'lere destek vermiyor: [spring.security.saml2.relyingparty.registration.{id}.identity-provider]
2) Artık buradaki property'leri kullanmalıyız: [spring.security.saml2.relyingparty.registration.{id}.asserting-party]
c. WebSecurityConfigurerAdapter deprecated oldu.

6. Spring Batch: Batch işlemlerinde yapılan değişiklikleri anlayarak geçiş sürecini planlayın.

  • @EnableBatchProcessing Kullanımı:
1. Bu anotasyonu kullanarak, Spring Batch auto-configuration yapılıyor, yeni versiyonda artık bunu önermiyor.
  • Birden Fazla Job’u Yönetme:
1. Önceden Spring Batch ile birden fazla batch işini aynı anda çalıştırmak mümkündü. Ancak artık durum böyle değil.
2. Auto-configuration sadece bir job tespit eder ve uygulama çalışmaya başlarken onu çalıştırır.
3. Eğer birden fazla job aynı context içerisinde yer alıyorsa, startup zamanı hangisinin çalıştırılması gerektiğini belirtmemiz gerekiyor.
a. spring.batch.job.name property kullanılarak hangi job çalıştırılmalı ayarlanabiliyor.
4. Eğer birden fazla job çalıştırmak istiyorsak, ayrı uygulamalar oluşturmak gerekiyor her bir job için.
5. Alternatif olarak, scheduler kullanılabilir, örneğin; Quartz, Spring Scheduler veya diğer alternatifler.

7. Spring Kafka: Kafka kullanıcıları için önemli değişikliklere odaklanarak, bu modülü güncelleyin.

  • Transaction-Id ve Kafka Template Değişiklikleri:
1. Transaction-Id
a. Önceki versiyonda transactional.id = transactionIdPrefix + n (0, 1, 2, .. her bir producer için +1)
b. EOSMode.V2 ile artık bu durum değişti. Bir çok instance ile çalışan uygulamalarda, her bir instance için transactionIdPrefix unique olmalı.
c. Spring Kafka 3 ile her bir uygulama instance'ı için unique bir transactionIdPrefix değeri oluşturmak gerekiyor.

2. Kafka Template
a. Yeni versiyonda ListenableFuture dönen methodlar, CompletableFuture dönmeye başladı.

Akbank Teknoloji çatısı altında geleceğin teknolojilerine uyum sağlamak için yapılan çalışmaları yakından takip edebilmek ve bu bilgi ağını genişletmek için bizi takipte kalın!

Bu Geçiş Rehberi’nin hazırlanması aşamasında, Maliyet — Kazanç (CostBenefit) kısmında yaptığı çalışmalardan dolayı takım arkadaşım Ziya Orujaliyev’e teşekkür ediyorum.

Referanslar
Spring-Boot-3.0-Migration-Guide
spring-boot-3-migration

--

--