Spring Boot
Spring Boot 4 ve Spring Framework 7 çizgisinde otomatik yapılandırma, bağımlılık enjeksiyonu, MVC/REST, Jakarta Persistence, transaction, güvenlik, test, HTTP istemcileri, virtual thread, gözlemlenebilirlik, Native Image ve üretim güvenilirliğini ele alan ileri ders notu.
Spring Boot, Spring Framework üzerinde çalışan uygulamalarda altyapı yapılandırmasını, bağımlılık sürümlerini, çalışma zamanı entegrasyonlarını ve paketlemeyi tutarlı varsayımlarla bir araya getirir. Çerçevenin asıl değeri yalnız birkaç anotasyonla HTTP uç noktası açmak değildir; bağımlılık enjeksiyonu, dış yapılandırma, veri erişimi, işlem (transaction) sınırları, güvenlik, test, gözlemlenebilirlik ve dağıtım kararlarını aynı uygulama yaşam döngüsünde yönetebilmesidir.
Spring Boot 4.1.1, Spring Framework 7.0.9 veya üzerini gerektirir; en az Java 17 ile çalışır ve resmî uyumluluk aralığı Java 26'ya kadar uzanır. Örneklerde Java 25 LTS kullanılabilir. Java 27 yayımlanmış olsa da Spring Boot 4.1.1'in resmî sistem gereksinimleri henüz Java 27 desteğini ilan etmez. Sürüm yükseltmelerinde uygulama koduyla birlikte starter adları, Jakarta paketleri, JSON yığını, test modülleri ve üçüncü taraf entegrasyonları kontrol edilmelidir.
1. Spring Framework ile Spring Boot arasındaki sınır
Spring Framework; IoC kapsayıcısı, bağımlılık enjeksiyonu, AOP, işlem yönetimi, web katmanı, veri erişimi ve entegrasyon bileşenlerini sağlar. Spring Boot bu yeteneklerin yerine geçen ayrı bir framework değildir. Spring ekosistemini belirli sürüm kümeleri, otomatik yapılandırmalar, starter bağımlılıkları, executable paketleme ve işletim özellikleriyle daha deterministik biçimde başlatır.
Temel ayrım şöyledir:
Spring Framework = programlama modeli + altyapı soyutlamaları
Spring Boot = opinionated başlangıç + auto-configuration + sürüm yönetimi + işletim katmanıBoot'un varsayımları zorunlu değildir. Uygulama kendi bean'ini veya açık yapılandırmasını sağladığında birçok otomatik yapılandırma geri çekilir. Bu davranış @ConditionalOnClass, @ConditionalOnMissingBean, @ConditionalOnProperty gibi koşullar üzerinden kurulur.
2. Boot 4 proje tabanı ve yapı sistemi
Spring Boot 4 ile starter yapısı daha modüler hâle gelmiştir. MVC tabanlı yeni projelerde spring-boot-starter-webmvc tercih edilir; eski spring-boot-starter-web geçiş amacıyla bulunmakla birlikte deprecated durumdadır.
Maven için minimal bir servis tabanı:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>4.1.1</version>
</parent>
<properties>
<java.version>25</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>Boot dependency management kullanıldığında, yönetilen bağımlılıkların sürümlerini rastgele tek tek sabitlemek yerine uyumlu BOM çizgisi korunmalıdır. Güvenlik veya hata düzeltmesi nedeniyle override gerekiyorsa bunun neden ve etkisi ayrıca kaydedilmelidir.
3. Uygulama başlangıcı ve paket sınırı
Tipik giriş noktası @SpringBootApplication ile tanımlanır:
package tr.example.orders;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}Bu anotasyon; yapılandırma, component scanning ve auto-configuration davranışlarını bir araya getirir. Ana sınıfı uygulamanın kök paketinde tutmak, bileşen ve entity taramasının doğal sınırını oluşturur. Geniş scanBasePackages kullanmak başlangıçta kolay görünse de modül sınırlarını belirsizleştirebilir.
4. IoC kapsayıcısı, bean ve bağımlılık enjeksiyonu
Spring nesne grafiğini ApplicationContext içinde yönetir. @Component, @Service, @Repository, @Controller ve @RestController farklı katman niyetlerini ifade eder; her birini yalnız “bean üretme etiketi” olarak görmek mimari bilgiyi kaybettirir.
Constructor injection varsayılan seçim olmalıdır:
@Service
public final class PriceService {
private final TaxPolicy taxPolicy;
public PriceService(final TaxPolicy taxPolicy) {
this.taxPolicy = taxPolicy;
}
public BigDecimal gross(final BigDecimal net) {
return net.add(taxPolicy.taxFor(net));
}
}Constructor injection bağımlılıkları görünür, zorunlu ve test edilebilir hâle getirir. Alan enjeksiyonu ise nesnenin geçerli durumunu constructor dışına taşır ve framework olmadan örneklemeyi zorlaştırır.
Birden fazla implementasyon varsa @Qualifier, @Primary veya daha açık bir domain factory kullanılabilir. Çözüm, belirsizliği rastgele bean adına bırakmamalıdır.
5. Otomatik yapılandırma nasıl çalışır
Auto-configuration classpath, mevcut bean'ler, property'ler ve uygulama türü gibi sinyallere göre koşullu bean tanımları sağlar. Boot 4'te auto-configuration altyapısı daha küçük teknoloji modüllerine ayrılmıştır; eski tek büyük spring-boot-autoconfigure algısıyla paket yapısına bağımlı kod yazılmamalıdır.
Auto-configuration bir “sihir” değildir. Hangi yapılandırmanın devreye girdiğini anlamak için:
- koşullu anotasyonlara,
- configuration özellikler üst veri'sına,
- condition evaluation report'a,
- uygulamadaki explicit bean tanımlarına
bakılır.
Starter eklemek uygulamaya yalnız jar eklemek değil, çoğu durumda belirli auto-configuration sınıflarını da erişilebilir hâle getirmek demektir.
6. Dış yapılandırma ve tip güvenli özellikler
Bağlantı adresleri, zaman aşımı değerleri, özellik bayrakları ve ortam bağımlı seçenekler kod sabiti olmamalıdır. Spring Boot property kaynaklarını belirli bir precedence ile birleştirir. Aynı anahtar farklı kaynaklarda tanımlanmışsa daha yüksek öncelikli kaynak sonucu belirler.
İlişkili ayarları @ConfigurationProperties ile tip güvenli modele bağlamak, çok sayıda dağınık @Value kullanımından daha sürdürülebilirdir:
package tr.example.orders.config;
import java.time.Duration;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("orders.remote")
public record RemoteOrderProperties(String baseUrl, Duration connectTimeout, Duration readTimeout) {
}@Configuration
@EnableConfigurationProperties(RemoteOrderProperties.class)
class OrderConfiguration {
}YAML karşılığı:
orders:
remote:
base-url: https://api.example.test
connect-timeout: 2s
read-timeout: 5sParola, token ve özel anahtarlar normal source-control yapılandırmasına yazılmamalıdır. Secret yönetimi, dağıtım ortamının güvenlik modeline göre ayrı ele alınmalıdır.
7. Profil kullanımı ve ortam ayrımı
dev, test, prod gibi profiller farklı bean veya property kümelerini etkinleştirebilir. Profil, iş kuralı seçme mekanizmasına dönüşmemelidir. İş davranışını environment adına göre dallandırmak yerine domain politikası veya açık configuration tercih edilmelidir.
Aynı binary'nin farklı ortamda yalnız yapılandırmayla çalışabilmesi; release bütünlüğü, rollback ve hata analizi açısından değerlidir.
Native Image kullanıldığında build-time AOT analizi nedeniyle çalışma anında bean grafiğini değiştiren bazı dinamik profil/koşul kalıplarının sınırlamaları ayrıca değerlendirilmelidir.
8. Spring MVC istek işleme zinciri
Servlet tabanlı Spring MVC akışının merkezinde DispatcherServlet vardır. İstek uygun handler mapping üzerinden controller metoduna yöneltilir; argument resolver'lar parametreleri hazırlar; dönüş değeri message converter veya view resolver tarafından işlenir.
@RestController
@RequestMapping("/api/orders")
public final class OrderController {
private final OrderService service;
public OrderController(final OrderService service) {
this.service = service;
}
@GetMapping("/{id}")
public OrderResponse find(@PathVariable final long id) {
return service.find(id);
}
}Controller'ın repository'ye doğrudan erişmesi kısa örnekte az kod üretir; büyük sistemde authorization, transaction ve domain kuralı sınırlarını karıştırır. Controller HTTP sözleşmesini, service use-case'i, repository ise persistence sınırını temsil etmelidir.
9. HTTP sözleşmesi ve REST API tasarımı
REST uç nokta tasarımında URI, HTTP metodu, durum kodu ve temsil formatı birlikte sözleşmedir. GET veri okumak, POST çoğunlukla yeni işlem/kaynak başlatmak, PUT belirli kaynağın tam idempotent güncellemesini, PATCH kısmi değişikliği, DELETE silme semantiğini ifade eder.
Her CRUD metodunu otomatik olarak dış API yapmak doğru değildir. Domain komutu çoğu zaman daha açık bir URI ve body gerektirir.
public record CreateOrderRequest(@NotBlank String customerCode,
@NotEmpty List<@Valid OrderLineRequest> lines) {
}
public record OrderLineRequest(@NotBlank String productCode,
@Positive int quantity) {
}@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public OrderResponse create(@Valid @RequestBody final CreateOrderRequest request) {
return service.create(request);
}DTO ile entity ayrımı, dış sözleşmenin persistence modeline bağımlı olmasını önler. Entity'yi doğrudan JSON'a açmak lazy-loading, recursive graph, veri sızıntısı ve versiyonlama sorunları doğurabilir.
10. JSON: Boot 4 ile Jackson 3
Spring Boot 4'te JSON için tercih edilen ve varsayılan Jackson sürümü Jackson 3'tür. Jackson 2 desteği geçiş amacıyla korunmuş fakat deprecated edilmiştir. Boot 3'ten yükseltirken package değişimleri, modül uyumluluğu ve özel serializer/deserializer sınıfları kontrol edilmelidir.
JSON modelinde eksik alan, null, bilinmeyen alan, tarih/saat biçimi ve enum değişiklikleri API uyumluluğunun parçasıdır. İstemci ile sunucunun aynı Java sınıfını paylaşması sözleşme yönetiminin yerine geçmez.
XML gerekiyorsa content negotiation ve uygun message converter kullanılabilir; fakat JSON ve XML aynı nesne grafiğini farklı güvenlik davranışlarıyla dışarı sızdırmamalıdır.
11. Doğrulama: sözdizimsel doğruluk ile iş kuralını ayırmak
Jakarta Bean Validation; boşluk, uzunluk, sayı aralığı ve format gibi sınır doğrulamalarında etkilidir. “Müşterinin kredi limiti yeterli mi?” gibi veriye ve bağlama bağlı kurallar ise service/domain katmanında ele alınmalıdır.
public record RegisterCustomerRequest(
@NotBlank @Size(max = 80) String name,
@Email @Size(max = 254) String email) {
}@Valid yalnız doğru sınırda uygulanmalıdır. Bir request içinde yüz binlerce nested nesneyi sınırsız validate etmek CPU ve bellek yönünden saldırı yüzeyi oluşturabilir; payload boyutu ve koleksiyon limitleri ayrıca sınırlandırılmalıdır.
12. Hata yönetimi ve Problem Details
HTTP hata cevabı stack trace dökmek değildir. API; hata kategorisi, stabil hata kodu, güvenli mesaj ve gerektiğinde correlation kimliği gibi kontrollü alanlar üretmelidir.
Spring Framework'ün ProblemDetail desteği RFC 9457 uyumlu hata temsili kurmayı kolaylaştırır:
@RestControllerAdvice
public final class ApiExceptionHandler {
@ExceptionHandler(OrderNotFoundException.class)
public ResponseEntity<ProblemDetail> notFound(final OrderNotFoundException ex) {
ProblemDetail detail = ProblemDetail.forStatus(HttpStatus.NOT_FOUND);
detail.setTitle("Order not found");
detail.setProperty("code", "ORDER_NOT_FOUND");
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(detail);
}
}Veritabanı ayrıntısı, SQL, dosya yolu, secret, token veya iç sınıf adı dış istemciye taşınmamalıdır. Operasyon ekibinin ihtiyaç duyduğu teknik detay ayrı log/izleme kanalında tutulur.
13. Spring Data JPA ve Jakarta Persistence
Spring Data JPA 4.x, Jakarta Persistence API üzerinde repository desteği sağlar. javax.persistence kullanan eski kod, modern Spring Boot çizgisinde jakarta.persistence paketlerine taşınmalıdır.
@Entity
@Table(name = "orders")
public class OrderEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, length = 40)
private String customerCode;
@Version
private long version;
protected OrderEntity() {
}
public OrderEntity(final String customerCode) {
this.customerCode = customerCode;
}
}Repository abstraction boilerplate'i azaltır; fakat sorgu maliyetini ortadan kaldırmaz. N+1, yanlış fetch stratejisi, büyük entity graph, kontrolsüz pagination ve gereksiz dirty checking üretimde temel performans sorunlarıdır.
public interface OrderRepository extends JpaRepository<OrderEntity, Long>, JpaSpecificationExecutor<OrderEntity> {
}Derived query isimleri küçük sorgularda okunabilirdir. Karmaşık koşullarda Specification, explicit JPQL veya ihtiyaca uygun başka bir query modeli daha doğru olabilir.
14. Transaction sınırı
@Transactional veritabanı transaction'ını method etrafında proxy/AOP ile yönetir. Transaction'ı controller boyunca açık tutmak yerine use-case sınırında tutmak daha öngörülebilirdir.
@Service
public class OrderCommandService {
private final OrderRepository repository;
public OrderCommandService(final OrderRepository repository) {
this.repository = repository;
}
@Transactional
public long create(final String customerCode) {
return repository.save(new OrderEntity(customerCode)).getId();
}
}Dikkat edilmesi gerekenler:
- aynı sınıf içindeki self-invocation proxy'yi aşabilir,
- checked/unchecked istisna rollback davranışı açıkça bilinmelidir,
- uzak HTTP çağrısını uzun DB transaction'ı içinde bekletmek kilit süresini uzatır,
- isolation seviyesi gerçek tutarlılık gereksinimine göre seçilmelidir,
- retry ile transaction tekrarının idempotency etkisi birlikte düşünülmelidir.
15. Şema yönetimi
ddl-auto=update geliştirme kolaylığıdır; kontrollü production migration stratejisi değildir. Şema değişiklikleri sürümlenmiş migration ile yönetilmelidir.
Boot 4, Flyway ve Liquibase entegrasyonlarını starter/modül yapısı üzerinden destekler. Migration dosyası dağıtım artefaktının bir parçası olarak source control'da izlenmeli; ileri ve geri uyumluluk uygulama rollout modeliyle birlikte planlanmalıdır.
Zero-downtime değişiklikte tipik sıra şöyledir:
genişlet -> yeni kodu dağıt -> veriyi dönüştür -> eski kullanımı kaldır -> daraltÖrneğin kolon adını tek dağıtım'ta değiştirmek yerine geçiş süresinde iki sürümün birlikte çalışabilmesi sağlanır.
16. Spring Security: kimlik doğrulama ve yetkilendirme
Spring Security filter chain üzerinden authentication, authorization, CSRF, session, header ve diğer güvenlik kontrollerini uygular. Modern yapılandırmada SecurityFilterChain bean'i kullanılır:
@Configuration
@EnableMethodSecurity
public class SecurityConfiguration {
@Bean
SecurityFilterChain securityFilterChain(final HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/health").permitAll()
.anyRequest().authenticated())
.httpBasic(Customizer.withDefaults())
.build();
}
}Method security spring-boot-starter-security eklenince otomatik etkinleşmez; @EnableMethodSecurity açıkça etkinleştirilir. @PreAuthorize güncel ve ifade gücü yüksek seçenektir:
@PreAuthorize("hasAuthority('order:read')")
public OrderResponse find(final long id) {
return queryService.find(id);
}Kimlik doğrulama yapıldıktan sonra “kullanıcı giriş yaptı” demek yetmez. Nesne düzeyi authorization, tenant sınırı, kaynak sahipliği ve admin işlevleri ayrıca doğrulanmalıdır.
17. CSRF, CORS ve oturum modeli
CORS bir authentication veya authorization mekanizması değildir; tarayıcının cross-origin response paylaşım politikasını yönetir. CSRF ise özellikle cookie tabanlı kimlik doğrulamada kullanıcının tarayıcısını istemeden state-changing istek göndermeye zorlayan saldırı sınıfıdır.
Stateless bearer-token API ile server-side session kullanan web uygulamasının güvenlik ayarı aynı olmamalıdır. CSRF'yi yalnız “REST API” olduğu gerekçesiyle kapatmak yerine credential taşıma modeli incelenmelidir.
18. Uzak HTTP çağrıları: RestClient, WebClient ve HTTP Service Clients
Spring Framework 7'de RestTemplate deprecated durumdadır. Yeni senkron kodda RestClient, non-bkiliting/reactive akışta WebClient, interface tabanlı istemci sözleşmelerinde HTTP Service Clients tercih edilir.
@Bean
RestClient inventoryClient(final RestClient.Builder builder, final RemoteOrderProperties properties) {
return builder.baseUrl(properties.baseUrl()).build();
}public interface InventoryApi {
@GetExchange("/api/stock/{productCode}")
StockResponse get(@PathVariable String productCode);
}HTTP istemcisinde timeout, connection reuse, DNS, retry, circuit breaking, response boyutu ve idempotency ayrı kararlardır. Varsayılan timeout'a güvenmek kritik serviste kabul edilebilir bir politika değildir.
19. Senkron, reaktif ve virtual iş parçacığı modelleri
Spring MVC bloklayan programlama modeliyle çalışabilir; WebFlux ise Reactor tabanlı non-bkiliting akış içindir. “Reaktif daha hızlıdır” genellemesi doğru değildir. Model, I/O davranışı ve ekip karmaşıklığı birlikte değerlendirilmelidir.
Spring Boot Java 21+ üzerinde virtual iş parçacığı kullanımını destekler:
spring.threads.virtual.enabled=true
spring.main.keep-alive=trueBoot belgeleri en iyi deneyim için Java 24+ önerir. Virtual iş parçacığı açıldığında klasik iş parçacığı-pool ayarlarının önemli bir kısmı artık aynı anlamı taşımaz. Pinned virtual iş parçacığı, bağlantı havuzu ve uzak sistem kapasitesi throughput sınırı olmaya devam eder.
Virtual iş parçacığı sınırsız dış servis veya veritabanı concurrency'si demek değildir. Database connection pool 50 ise aynı anda binlerce virtual iş parçacığı DB'ye girmek istediğinde dar boğaz yine pool'dur.
20. Önbellek ve tutarlılık
Spring Cache abstraction @Cacheable, @CachePut ve @CacheEvict gibi anotasyonlarla önbellek sağlayıcısından bağımsız bir programlama modeli verir. Ancak önbellek invalidation domain kararıdır.
Cache anahtarı tenant, locale, authorization veya versiyon gibi sonucu etkileyen boyutları içermiyorsa veri sızıntısı veya yanlış cevap oluşabilir. TTL yalnız performans değil, kabul edilen bayatlık süresidir.
Dağıtık sistemde local önbellek her instance'ta farklı durum üretebilir. Tutarlılık ihtiyacı yüksek veride önbellek eklemek yerine önce query ve indeks maliyeti ölçülmelidir.
21. Mesajlaşma ve asenkron iş akışı
Kafka, AMQP/RabbitMQ ve benzeri broker entegrasyonları request-response zincirini ayırabilir. Mesajlaşma otomatik olarak güvenilirlik sağlamaz; delivery semantics, idempotent consumer, ordering, poison message ve dead-letter davranışı tasarlanmalıdır.
Bir DB transaction'ı ile broker publish işlemini iki bağımsız kaynak arasında atomikmiş gibi varsaymak hatalıdır. Outbox pattern gibi yöntemler, iş verisi ile publish niyetini aynı transaction'da kaydetmek için kullanılabilir.
22. Thymeleaf ve sunucu taraflı HTML
Thymeleaf, server-side rendered HTML için geçerli bir çözümdür. Controller model üretir, template HTML çıktısını oluşturur. Bu yaklaşım ayrı SPA katmanı gerektirmeyen uygulamalarda dağıtım ve state modelini sadeleştirebilir.
Template'e entity grafiği taşımak yerine view model kullanmak daha güvenlidir. Kullanıcı verisini raw HTML olarak basmak XSS riskini artırır; template engine'in escaping davranışı bilinçli biçimde korunmalıdır.
23. Test katmanları
Spring uygulamasında her testin @SpringBootTest olması gereksiz derecede pahalıdır. Test kapsamı ihtiyaca göre ayrılır:
- saf birim testi: Spring context açılmaz,
- MVC slice:
@WebMvcTest, - JPA slice:
@DataJpaTest, - entegrasyon:
@SpringBootTest, - gerçek servis bağımlılığı: Testcontainers ve
@ServiceConnection.
Boot 4 modüler test starter'ları sunar; kullanılan ana teknoloji starter'ının test karşılığı migration sırasında kontrol edilmelidir.
@WebMvcTest(OrderController.class)
class OrderControllerTest {
@Autowired
private MockMvc mockMvc;
@MockitoBean
private OrderService service;
@Test
void missingOrderReturns404() throws Exception {
when(service.find(42L)).thenThrow(new OrderNotFoundException(42L));
mockMvc.perform(get("/api/orders/42"))
.andExpect(status().isNotFound());
}
}Mock ile her şeyi taklit etmek, ORM mapping veya gerçek SQL davranışını test etmez. Persistence kritikse gerçek veritabanı motoruna yakın entegrasyon testi gerekir.
24. Actuator ve gözlemlenebilirlik
Actuator; health, info, metrics, loggers ve diğer işletim uç nokta'lerini sağlar. Uç nokta açmak ile internete yayınlamak aynı şey değildir. Exposure ve authorization ayrı yapılandırılmalıdır.
Spring Boot gözlemlenebilirlik modelinde log, metric ve trace üçlüsünü; metric ve trace tarafında Micrometer Observation altyapısını kullanır. Cardinality kontrolü üretim maliyetinin parçasıdır. Kullanıcı kimliği, request ID veya serbest metin gibi yüksek cardinality alanları metric tag olarak kontrolsüz kullanılmamalıdır.
Uygulamanın health cevabı da doğru modellenmelidir. Process'in ayakta olması, dış bağımlılıkların sağlıklı olduğu anlamına gelmez; buna karşılık her dış bağımlılığı liveness'a bağlamak zincirleme restart üretebilir.
25. Paketleme ve dağıtım
Executable JAR, modern Spring Boot servisleri için varsayılan paketleme yaklaşımıdır. WAR, harici servlet container gerektiren kurumsal ortamlarda hâlâ mümkündür; ancak ayrı container yönetimi zorunluluk değilse executable uygulama daha basit bir operasyon modeline sahiptir.
Container image oluştururken:
- immutable artefakt,
- non-root process,
- read-only filesystem ihtiyacı,
- JVM heap/container memory oranı,
- graceful shutdown,
- readiness/liveness ayrımı,
- SBOM ve dependency provenance
düşünülmelidir.
Boot build plugin'leri OCI image üretimini buildpack ile destekler.
26. GraalVM Native Image ve AOT
Spring Boot, GraalVM Native Image üretebilir. Native executable genellikle daha hızlı başlangıç ve daha küçük runtime memory footprint sağlar; bunun karşılığında build süresi, closed-world varsayımı ve reflection/resource üst veri gereksinimleri artar.
Native image seçimi ölçümle yapılmalıdır. Uzun ömürlü, yüksek throughput JVM servisi JIT optimizasyonundan yararlanabilir; kısa ömürlü veya hızlı cold-start gerektiren workload native image'dan daha fazla fayda görebilir.
Reflection, dynamic proxy, resource loading ve serialization gibi dinamik özellikler AOT sırasında reachability hint gerektirebilir.
27. Performans: framework ayarından önce darboğazı bulmak
Bir Spring Boot servisinin gecikmesi çoğu zaman framework dispatcher maliyetinden değil şu katmanlardan gelir:
DB sorgusu
uzak servis RTT
connection pool bekleme
serialization
lock contention
GC/allocation
thread veya event-loop kuyruklarıBu nedenle optimizasyon sırası ölçüm odaklı olmalıdır. Request başına gereksiz entity graph, limitsiz listeler, kontrolsüz retry ve büyük JSON gövdeleri öncelikle ele alınır.
Virtual iş parçacığı, reactive stack veya native image mimari borcu otomatik çözmez. Her biri farklı bir darboğaz sınıfına yönelik araçtır.
28. Güvenilirlik ve hata toleransı
Timeout olmadan yapılan uzak çağrı kaynak tüketimini sınırsızlaştırabilir. Retry ise idempotent olmayan işlemde aynı siparişi veya ödemeyi iki kez üretebilir. Sağlam politika şu kavramları birlikte ele alır:
- connect/read/overall timeout,
- sınırlı retry ve backoff,
- idempotency key,
- bulkhead/concurrency sınırı,
- circuit breaker gerekiyorsa kontrollü kullanım,
- fallback'in veri doğruluğuna etkisi,
- queue/geri basınç.
Fallback “hata yokmuş gibi” sahte başarı üretmemelidir; business sözleşmesine göre stale/partial sonuç gerçekten kabul ediliyorsa açık biçimde modellenmelidir.
29. Katmanlar ve transaction dışı yan etkiler
Tipik akış:
HTTP adapter -> application service -> domain -> repository / external adapterBu bir zorunlu paket şablonu değil, bağımlılık yönünü görünür kılan düşünme aracıdır. Domain kodunun HTTP, JPA veya JSON annotation'larına gereksiz bağımlılığı azaltılırsa test ve migration daha kolay olur.
Transaction içinde e-posta, HTTP veya broker çağrısı yapmak iki-phase commit olmadığı sürece ayrı hata alanlarını tek atomik işlem gibi gösterir. Yan etkiler ve kalıcı state değişikliği gerektiğinde outbox, event veya explicit orchestration ile ayrılmalıdır.
30. Boot 2/3 kaynaklarını Boot 4'e taşırken
Eski eğitim materyalindeki bilgi kavramsal olarak değerli olabilir; API ve paket adları güncellenmelidir. Başlıca kontrol noktaları:
javax.*yerine modern Jakarta paketleri,spring-boot-starter-webyerine yeni projelerdespring-boot-starter-webmvc,- Jackson 3'e geçiş,
- eski security adapter yapılandırmaları yerine
SecurityFilterChain, @EnableGlobalMethodSecurityyerine@EnableMethodSecurity,- yeni senkron HTTP istemcilerinde
RestClient, RestTemplateiçin deprecation/migration planı,- teknolojiye özel Boot 4 starter ve test starter'ları,
- AOT/native image kullanılıyorsa dinamik yapıların yeniden kontrolü.
Migration'da ilk hedef “derleniyor” değil, davranış eşdeğerliğidir. Serialization, validation, security filter ordering, transaction ve DB migration davranışları regression test ile doğrulanmalıdır.
31. Uçtan uca küçük servis örneği
Aşağıdaki yapı HTTP sözleşmesini, application service'i ve repository'yi ayırır:
public record CreateDeviceRequest(@NotBlank String serialNumber) {
}
public record DeviceResponse(long id, String serialNumber) {
}@Entity
@Table(name = "device")
class DeviceEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true, length = 64)
private String serialNumber;
protected DeviceEntity() {
}
DeviceEntity(final String serialNumber) {
this.serialNumber = serialNumber;
}
Long id() {
return id;
}
String serialNumber() {
return serialNumber;
}
}interface DeviceRepository extends JpaRepository<DeviceEntity, Long> {
}@Service
class DeviceService {
private final DeviceRepository repository;
DeviceService(final DeviceRepository repository) {
this.repository = repository;
}
@Transactional
DeviceResponse create(final CreateDeviceRequest request) {
DeviceEntity entity = repository.save(new DeviceEntity(request.serialNumber()));
return new DeviceResponse(entity.id(), entity.serialNumber());
}
}@RestController
@RequestMapping("/api/devices")
class DeviceController {
private final DeviceService service;
DeviceController(final DeviceService service) {
this.service = service;
}
@PostMapping
ResponseEntity<DeviceResponse> create(@Valid @RequestBody final CreateDeviceRequest request) {
DeviceResponse response = service.create(request);
return ResponseEntity.status(HttpStatus.CREATED).body(response);
}
}Bu örnek bilinçli olarak caching, security ve uzak çağrı içermiyor. Her yeni altyapı bileşeni yalnız gerçek gereksinim varsa eklenmelidir.
32. İlgili dersler
Spring Boot, Java Programlama dil ve JVM bilgisinin uygulama çatısı üzerindeki devamıdır. HTTP ve istemci-sunucu modeli için Web Programlama, persistence ve transaction için Veri Tabanı Yönetim Sistemleri, mimari ve kalite kararları için Yazılım Mühendisliği, dil ve çalışma zamanı karşılaştırmaları için Programlama Dilleri birlikte okunabilir.
Kaynaklar
- Spring, Spring Boot Reference Documentation — 4.1.x. https://docs.spring.io/spring-boot/
- Spring, Spring Boot System Requirements. https://docs.spring.io/spring-boot/system-requirements.html
- Spring, Spring Framework Reference Documentation — 7.0.x. https://docs.spring.io/spring-framework/reference/
- Spring, Spring Security Reference — Method Security. https://docs.spring.io/spring-security/reference/servlet/authorization/method-security.html
- Spring, Spring Data JPA Reference Documentation. https://docs.spring.io/spring-data/jpa/reference/
- Spring, Spring Boot JSON Support — Jackson 3. https://docs.spring.io/spring-boot/reference/features/json.html
- Spring, Spring Boot Testcontainers and Service Connections. https://docs.spring.io/spring-boot/reference/testing/testcontainers.html
- Spring, Spring Boot Observability. https://docs.spring.io/spring-boot/reference/actuator/observability.html
- Spring, GraalVM Native Images with Spring Boot. https://docs.spring.io/spring-boot/how-to/native-image/
- Oracle, Java SE Downloads and Release Information. https://www.oracle.com/java/technologies/downloads/