Ana Sayfa/Java & Kurumsal Mimari
Java & Kurumsal Mimari·4 Kasım 2026·10 dk okuma

JDK 28’de ‘JEP 401 Value Classes’ ve Değişmez Veri Mimarisi, Spring AI 2.1 ‘MessagePart’ Akıl Yürütme Korunumu ve Özel Vektör ‘Upsert’ API’si

OpenJDK 28 erken erişim sürümlerinde 30 çekirdek sınıfı kimliksiz değer nesnesine dönüştüren JEP 401 (Value Classes), çok turlu akıl yürütme imzalarını kayıpsız taşıyan Spring AI 2.1 MessagePart mimarisi ve önceden hesaplanmış float[] vektörleri destekleyen VectorStore.upsert() yetenekleri inceleniyor.

JDK 28’de ‘JEP 401 Value Classes’ ve Değişmez Veri Mimarisi, Spring AI 2.1 ‘MessagePart’ Akıl Yürütme Korunumu ve Özel Vektör ‘Upsert’ API’si

Modern JVM ve Spring Ekosisteminde Üç Mimari Dönüşüm: Kimliksiz Bellek, Kayıpsız Akıl Yürütme ve Doğrudan Vektör Enjeksiyonu

Kurumsal Java ekosistemi, bir yandan Project Valhalla ve Project Amber ile JVM'in otuz yıllık nesne kimliği (object identity) ve değişmezlik (immutability) varsayımlarını yeniden inşa ederken; diğer yandan Spring AI 2.1 ile çok turlu akıl yürütme (reasoning) modellerinin ve yüksek hacimli vektör boru hatlarının üretim darboğazlarını çözüyor. Inside.java ve Spring.io resmi mühendislik bültenlerinde yayımlanan üç temel gelişme bu mimari evrimi şekillendiriyor:

  1. JDK 28 ‘JEP 401 Value Classes’ ve Değişmez Veri Ekosistemi: --enable-preview bayrağı altında Integer, Double, Long ve LocalDate dahil 30 çekirdek JDK sınıfının kimliksiz değer sınıfına (value class) dönüşmesi, == semantiği ile synchronized / WeakHashMap / setAccessible davranış değişiklikleri ve JavaOne 2026 kapsamında detaylandırılan bütünsel değişmez veri mimarisi.
  2. Spring AI 2.1 ‘Message Parts’ ve ‘OpaquePayload’ Mimarisi: OpenAI Responses API, Anthropic Claude, Google Gemini ve DeepSeek-R1 gibi modellerin çok turlu araç çağrılarında ürettiği kriptografik düşünce imzalarının (thought signatures) kaybolmasını önleyen sıralı MessagePart (ReasoningPart, ToolCallPart vb.) veri modeli.
  3. Spring AI 2.1 ‘Using Your Own Embeddings’ ve VectorStore.upsert() API’si: Harici GPU boru hatlarında veya çok modlu (multimodal) modellerde önceden hesaplanmış float[] vektörlerin yeniden hesaplama maliyeti olmadan doğrudan VectorStore üzerine yazılması ve ham vektörle similaritySearch yürütülmesi.

1. JDK 28 ve Project Valhalla (JEP 401): 30 Çekirdek Sınıfta ‘Value Classes’ Dönüşümü

OpenJDK Quality Outreach ekibi tarafından yayımlanan JDK 28: Value Classes teknik uyarısı ve Oracle Kıdemli Java Platform Geliştiricisi Dan Smith ile Nicolai Parlog'un gerçekleştirdiği "Immutable Data Beyond Value Classes" (Bölüm 73) mimari incelemesi, Java'da değer nesnelerinin çalışma zamanı etkilerini netleştiriyor.

JEP 401 (Value Classes and Objects) ile birlikte, nesne kimliğine (object identity) ihtiyaç duymayan saf veri taşıyıcıları value class veya value record anahtar sözcükleriyle tanımlanabiliyor. JDK 28 Early-Access derlemelerinde önizleme özellikleri (--enable-preview) etkinleştirildiğinde, standart kütüphanedeki 30 çekirdek JDK sınıfı otomatik olarak değer sınıfına dönüşüyor:

  • İlkel Sarmalayıcı Sınıflar (Primitive Wrappers): java.lang.Byte, Short, Integer, Long, Float, Double, Character, Boolean.
  • Tarih ve Zaman Tipleri (java.time): LocalDate, LocalTime, LocalDateTime, ZonedDateTime, OffsetDateTime, OffsetTime, Instant, Duration, Period, Year, YearMonth, MonthDay.
  • İsteğe Bağlı Kapsayıcılar (java.util): Optional, OptionalInt, OptionalLong, OptionalDouble.
mermaid
flowchart TD
    subgraph Pillar1["1. JDK 28 JEP 401 & Değişmez Veri Mimarisi"]
        V1["30 Çekirdek JDK Sınıfı (Integer, LocalDate, Optional)"]
        V2["Kimliksiz (Identity-Free) Düz Bellek & Skalarlaştırma"]
        V3["Esnek Kurucular + Records + Withers + Lazy Constants"]
        V1 --> V2 --> V3
    end

    subgraph Pillar2["2. Spring AI 2.1 MessagePart & Reasoning Replay"]
        M1["Çok Turlu Reasoning LLM (Claude / Gemini / OpenAI)"]
        M2["Sıralı MessagePart Listesi (TextPart, ReasoningPart)"]
        M3["OpaquePayload ile Kriptografik İmza Korunumu"]
        M1 --> M2 --> M3
    end

    subgraph Pillar3["3. Spring AI 2.1 Özel Vektör & Upsert API"]
        E1["Harici GPU Batch / Multimodal (CLIP) float[] Vektörleri"]
        E2["VectorStore.upsert(Document + float[]) Doğrudan Yazım"]
        E3["similaritySearch(float[] queryVector) Ham Vektör Sorgusu"]
        E1 --> E2 --> E3
    end

Kimlik Kaybının (Loss of Identity) Kırıcı Davranışsal Etkileri

Değer nesneleri bellekte tekil bir adres kimliğine sahip olmadığından, JIT derleyicisi bu nesneleri yığın (heap) üzerinde dolaylı işaretçiler (indirection pointers) olmadan dizilerin içine düz (flat) olarak yerleştirebiliyor ve CPU yazmaçlarında (registers) skalarlaştırabiliyor. Ancak bu dönüşüm, nesne kimliğine güvenen eski kodlarda dört kritik davranış değişikliği yaratıyor:

  1. == Operatörü (Substitutability Test): Değer nesnelerinde == artık bellek adresini değil, nesnenin tüm alanlarının bit düzeyinde eşit olup olmadığını kontrol ediyor. Örneğin new Integer(1000) yerine kullanılan iki farklı Integer.valueOf(1000) çağrısı, önbellek aralığı (-128..127) dışında olsa dahi == ile her zaman true döndürüyor.
  2. Senkronizasyon Yasağı (synchronized): Kimliksiz bir nesnenin monitör kilidi olamayacağı için synchronized(localDateInstance) veya synchronized(integerInstance) ifadeleri derleme zamanında veya çalışma zamanında IdentityException ile reddediliyor.
  3. Kimlik Duyarlı Koleksiyonlar ve Referanslar: WeakHashMap, IdentityHashMap veya java.lang.ref.WeakReference / PhantomReference yapıları kimliksiz değer nesnelerini kabul etmiyor.
  4. Yansıma (Reflection) Kısıtlaması: Değer sınıflarının alanları kesin olarak değişmez (strictly final) olduğundan, Field.setAccessible(true) çağrısı InaccessibleObjectException fırlatıyor.

Value Classes Ötesinde Bütünsel Değişmez Veri Ekosistemi

Dan Smith'in vurguladığı üzere Java'da değişmez veri modellemesi tek bir özellikle değil, birbirini tamamlayan altı dil mekanizmasıyla inşa ediliyor: Flexible Constructor Bodies (super(...) öncesinde alan doğrulama ve normalizasyon), Records (şeffaf veri taşıyıcıları), Value Classes (kimliksiz düz bellek yerleşimi), Derived Record Creation / Withers (with ifadeleriyle değişmez kopya üretimi), Record Patterns (yapısal ayrıştırma) ve Lazy Constants (ilk erişimde güvenli tekil hesaplama).


2. Spring AI 2.1 ‘Message Parts’: Çok Turlu Akıl Yürütme İmzalarının Kayıpsız Korunması

Modern akıl yürütme (reasoning/thinking) modelleri (OpenAI Responses API, Anthropic Claude genişletilmiş düşünme modu, Google Gemini Thinking ve DeepSeek-R1), bir kullanıcının sorusunu yanıtlarken veya bir araç çağrısı (tool call) başlatırken arka planda çok adımlı bir içsel düşünce zinciri üretiyor. Sağlayıcılar, modelin bir sonraki konuşma turunda kendi düşünce bağlamını doğrulayabilmesi için bu blokları kriptografik olarak imzalanmış jetonlar (cryptographic thought signatures) veya şifreli durum blokları olarak döndürüyor.

Eski Mesaj Modelinin Sınırları ve MessagePart Çözümü

Spring AI'ın önceki sürümlerinde AssistantMessage ve UserMessage sınıfları temel olarak tek bir metin dizesi (String text) ve buna eklenen yan özellikler (media, toolCalls) şeklinde modelleniyordu. Çok turlu bir araç çağrısı döngüsünde mesaj geçmişi (ChatMemory) kaydedilip modele geri gönderildiğinde:

  • Düşünce blokları ve metin parçaları arasındaki kesin sıra kayboluyor,
  • Sağlayıcıya özgü kriptografik düşünce imzaları düz metne indirgenirken düşürülüyor ve sağlayıcı API'si HTTP 400 Invalid Signature / Missing Thinking Block hatası döndürüyordu.

Spring AI 2.1, mesaj veri modelini kökten değiştirerek içeriği sıralı ve polimorfik bir List<MessagePart> koleksiyonu olarak yapılandırıyor:

  • TextPart: Standart metin içerikleri.
  • ReasoningPart: Modelin ürettiği içsel akıl yürütme metni ve doğrulama imzası.
  • ToolCallPart & ToolResultPart: Araç çağrısı istemleri ve yürütme sonuçları.
  • MediaPart: Çok modlu görüntü, ses ve belge ekleri.
  • UnknownPart & OpaquePayload: Henüz standartlaşmamış veya sağlayıcıya özgü ikili/şifreli verileri (Anthropic/Gemini düşünce imzaları gibi) hiçbir değişikliğe uğratmadan (byte-for-byte) bellek katmanından geçirip modele geri ileten opak yük taşıyıcısı.
Mimari Özellik JDK 28 ‘JEP 401 Value Classes’ Spring AI 2.1 ‘Message Parts’ Spring AI 2.1 ‘Custom Embeddings’
Çözülen Darboğaz Nesne başlığı (Mark Word) ve işaretçi dolaylaması yükü Çok turlu araç çağrılarında akıl yürütme imzası kaybı VectorStore yazımlarında zorunlu metin-vektör hesaplaması
Temel API / JEP JEP 401 (value class, value record, 30 JDK sınıfı) MessagePart, ReasoningPart, OpaquePayload VectorStore.upsert(), similaritySearch(float[])
Bellek ve Veri Temsili Kimliksiz, düz (flat) dizi yerleşimi ve CPU yazmaç skalarlaştırması Sıralı polimorfik parça listesi ve kayıpsız ikili imza korunumu Doğrudan uygulama tarafından sağlanan float[] gömme vektörleri
Kırıcı Değişiklik / Kısıt synchronized, WeakHashMap ve setAccessible reddi Düz String yerine sıralı parça listesi üzerinden mesaj inşası Harici vektör boyutu ile veritabanı indeks boyutunun eşleşme şartı
Üretim Kazanımı Yüksek önbellek yerelliği (cache locality) ve düşük GC baskısı Claude, Gemini ve OpenAI reasoning modellerinde sıfır bağlam kaybı Çok modlu (CLIP) ve toplu GPU vektörlerinde sıfır yeniden hesaplama

3. Spring AI 2.1 ‘Using Your Own Embeddings’: Doğrudan float[] Upsert ve Arama

Spring AI 2.1'in getirdiği bir diğer kritik kurumsal yetenek, vektör veritabanı (VectorStore) katmanının metin tabanlı EmbeddingModel bağımlılığından kurtarılmasıdır. Önceki mimaride vectorStore.add(documents) çağrıldığında Spring AI her belgenin metnini yapılandırılmış bir EmbeddingModel üzerinden geçirerek vektörü çalışma zamanında üretiyordu.

Ancak kurumsal veri mühendisliği senaryolarında bu zorunluluk üç büyük engel oluşturuyordu:

  1. Çevrimdışı GPU Batch Boru Hatları: Milyonlarca belgenin vektörleri zaten Apache Spark veya Ray kümelerinde önceden hesaplanmış (pre-computed) olduğunda, uygulama katmanında aynı vektörleri tekrar hesaplamak hem yüksek API maliyeti hem de gecikme yaratıyordu.
  2. Çok Modlu (Multimodal) Gömmeler: Görüntü, ses veya video varlıklarından CLIP / SigLIP gibi çok modlu modellerle üretilen vektörler metin tabanlı EmbeddingModel arayüzüne uymuyordu.
  3. Veritabanı Taşıma (Migration): Bir vektör veritabanından diğerine (PGVector -> Milvus / Qdrant) geçiş yaparken mevcut float[] vektörlerin birebir korunması gerekiyordu.

Spring AI 2.1, Document nesnelerine doğrudan önceden hesaplanmış float[] vektörlerin eklenmesine, VectorStore.upsert() ile idempotent olarak yazılmasına ve similaritySearch(float[] queryVector, ...) aşırı yüklemesiyle doğrudan ham sorgu vektörü üzerinden benzerlik araması yapılmasına olanak tanıyor.


Mühendislik Uygulaması: JEP 401 Değer Kaydı, MessagePart Akıl Yürütme Korunumu ve Vektör Upsert Mimarisi

Aşağıdaki referans Java uygulaması; JDK 28 value record semantiğini, Spring AI 2.1 tarzı kriptografik düşünce imzasını koruyan sıralı MessagePart / OpaquePayload yapısını ve önceden hesaplanmış float[] vektörlerle çalışan idempotent upsert + ham vektör benzerlik aramasını bir arada göstermektedir:

java
package com.tastutanlabs.architecture.java28;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * JDK 28 JEP 401 Value Record, Spring AI 2.1 MessagePart (Reasoning + OpaquePayload)
 * ve Pre-Computed float[] VectorStore Upsert referans mimarisi.
 */
public class ModernJavaSpringAiArchitecture {

    // 1. JDK 28 (JEP 401) Kimliksiz Değer Kaydı: Düz bellek yerleşimi ve durum tabanlı eşitlik
    public /* value */ record EmbeddingVectorSlice(String docId, float[] vector, String modality) {
        public EmbeddingVectorSlice {
            if (docId == null || docId.isBlank()) {
                throw new IllegalArgumentException("Belge kimliği boş olamaz.");
            }
            if (vector == null || vector.length == 0) {
                throw new IllegalArgumentException("Vektör dizisi boş olamaz.");
            }
            // Dışarıdan gelebilecek mutasyonlara karşı savunmacı kopya
            vector = Arrays.copyOf(vector, vector.length);
        }

        public double cosineSimilarity(float[] queryVector) {
            if (queryVector.length != vector.length) {
                throw new IllegalArgumentException("Vektör boyutları uyuşmuyor.");
            }
            double dot = 0.0, normA = 0.0, normB = 0.0;
            for (int i = 0; i < vector.length; i++) {
                dot += vector[i] * queryVector[i];
                normA += vector[i] * vector[i];
                normB += queryVector[i] * queryVector[i];
            }
            return dot / (Math.sqrt(normA) * Math.sqrt(normB));
        }
    }

    // 2. Spring AI 2.1 MessagePart ve OpaquePayload Hiyerarşisi
    public sealed interface MessagePart permits ReasoningPart, ToolCallPart, TextPart {}

    public record OpaquePayload(String providerId, byte[] cryptographicSignature) {
        public String toBase64Signature() {
            return Base64.getEncoder().encodeToString(cryptographicSignature);
        }
    }

    public record ReasoningPart(String thinkingSummary, OpaquePayload opaquePayload) implements MessagePart {}
    public record ToolCallPart(String callId, String toolName, String jsonArgs) implements MessagePart {}
    public record TextPart(String content) implements MessagePart {}

    public static final class RoundTripAssistantMessage {
        private final List<MessagePart> parts;

        public RoundTripAssistantMessage(List<MessagePart> parts) {
            this.parts = List.copyOf(parts);
        }

        public List<MessagePart> parts() {
            return parts;
        }

        public boolean hasIntactReasoningSignature() {
            return parts.stream()
                .filter(ReasoningPart.class::isInstance)
                .map(ReasoningPart.class::cast)
                .anyMatch(r -> r.opaquePayload() != null && r.opaquePayload().cryptographicSignature().length > 0);
        }
    }

    // 3. Spring AI 2.1 Doğrudan float[] Upsert ve Ham Vektör SimilaritySearch Motoru
    public static final class CustomEmbeddingVectorStore {
        private final Map<String, EmbeddingVectorSlice> index = new ConcurrentHashMap<>();

        public void upsert(List<EmbeddingVectorSlice> preComputedDocs) {
            for (EmbeddingVectorSlice slice : preComputedDocs) {
                index.put(slice.docId(), slice);
            }
        }

        public List<String> similaritySearch(float[] rawQueryVector, double minScore) {
            List<String> matches = new ArrayList<>();
            for (EmbeddingVectorSlice slice : index.values()) {
                double score = slice.cosineSimilarity(rawQueryVector);
                if (score >= minScore) {
                    matches.add(String.format("%s (modality=%s, score=%.4f)", slice.docId(), slice.modality(), score));
                }
            }
            return matches;
        }
    }

    public static void main(String[] args) {
        // A. Spring AI 2.1 ReasoningPart + OpaquePayload gidiş-dönüş doğrulaması
        OpaquePayload signature = new OpaquePayload(
            "anthropic-claude-thinking-v1",
            "sig_sha256_99f8a7b6c5d4e3".getBytes(StandardCharsets.UTF_8)
        );
        RoundTripAssistantMessage assistantTurn = new RoundTripAssistantMessage(List.of(
            new ReasoningPart("Veritabanı şeması ve indeks seçiciliği değerlendirildi.", signature),
            new ToolCallPart("call_01", "executeSqlExplain", "{\"query\": \"SELECT * FROM orders\"}"),
            new TextPart("Sorgu planı analizi başlatıldı.")
        ));
        System.out.println("Reasoning İmzası Korundu mu: " + assistantTurn.hasIntactReasoningSignature());

        // B. Spring AI 2.1 Pre-Computed float[] Upsert ve Ham Vektör Sorgusu
        CustomEmbeddingVectorStore store = new CustomEmbeddingVectorStore();
        store.upsert(List.of(
            new EmbeddingVectorSlice("doc_cad_turbine_01", new float[]{0.88f, 0.42f, 0.19f}, "MULTIMODAL_3D"),
            new EmbeddingVectorSlice("doc_legal_clause_09", new float[]{0.12f, 0.91f, 0.35f}, "BATCH_TEXT")
        ));

        List<String> results = store.similaritySearch(new float[]{0.86f, 0.45f, 0.21f}, 0.95);
        System.out.println("Ham Vektör Arama Sonuçları: " + results);
    }
}

Mimari Değerlendirme

JDK 28'de JEP 401 ile 30 temel sınıfın kimliksiz değer nesnesine dönüşmesi, Java'nın yüksek frekanslı finans, oyun motorları ve yapay zeka veri boru hatlarında C++/Rust seviyesinde bellek yoğunluğuna ulaşmasını sağlıyor. Uygulama katmanında ise Spring AI 2.1, MessagePart / OpaquePayload ile çok turlu akıl yürütme modellerinin durum bütünlüğünü garanti altına alırken; VectorStore.upsert() ve ham float[] arama desteğiyle kurumsal veri mühendisliği boru hatlarını çerçeve kısıtlamalarından özgürleştiriyor.

Konu Etiketleri
#Kurumsal Mimari#Project Valhalla#JEP 401#MessagePart#Java 28#Spring AI 2.1#Value Classes#VectorStore
Emre Taştutan
Emre TaştutanGeliştirici & AI Meraklısı

Yazılım mimarisi, mikroservis ekosistemleri ve üretken yapay zeka uygulamaları üzerine çalışıyorum. TastutanLabs çatısı altında geliştirici araçları ve SaaS ürünleri inşa ediyorum.

@tastutanlabs • Instagram Mini-Blog

Bu analizin 6 kartlık görsel özetini Instagram'da inceleyin ve kaydedin

Her gün yazılım mimarisi, Java/JVM ve yapay zeka gelişmelerini kendi başına okunabilen 6 slaytlık Mini-Blog serileri halinde paylaşıyoruz.

Instagram'da Takip Et →
Bu Yazıyı Paylaş:

Yorumlar (0)

Düşüncelerinizi Paylaşın

Henüz yorum yapılmamış. İlk yorumu siz yapın!

Bu Kategorideki Diğer İncelemeler

Java & Kurumsal Mimari

OpenJDK ‘Project Detroit’ (FFM ile V8 ve CPython), Spring Boot Yerel ‘Cloud Foundry / kind’ Orkestrasyonu ve Quarkus 4.0 Mimarisi

OpenJDK'nın Foreign Function & Memory (FFM) API üzerinden Google V8 ve CPython çalışma zamanlarını doğrudan JVM sürecine gömen Project Detroit girişimi, Spring Boot uygulamalarında Docker/kind tabanlı yerel Cloud Foundry dağıtımı ve Quarkus 4.0 (Vert.x 5, HTTP/3, Hibernate 8) mimarisi inceleniyor.

Emre TaştutanEmre Taştutan
9 dk