Veille Spring Boot — semaine du 02/11/2026
Spring AI 2.1 : les message parts préservent le raisonnement entre deux appels
Spring Blog · 28/10/2026
En bref : Spring AI 2.1 remplace le texte simple d'un message par une liste ordonnée de MessagePart. Les blocs de raisonnement, leurs signatures et les appels d'outils gardent ainsi leur ordre et peuvent être renvoyés tels quels au modèle.
Ce qu'il faut retenir :
AbstractMessageexpose désormaisgetParts(), une liste ordonnée partagée par tous les types de messages.MessagePartest une interfacesealedavec six records :TextPart,ReasoningPart,ToolCallPart,ToolResultPart,MediaPartetUnknownPart(JSON brut des blocs non modélisés).OpaquePayload(provider, kind, data)transporte les données opaques (signature Anthropic,thought_signatureGemini,encrypted_contentOpenAI). Le modèle qui les a produites les renvoie sans les modifier, et les autres les ignorent.getReasoning()offre un accesseur unique pour le raisonnement, quel que soit le modèle. Avant 2.1, chaque modèle l'exposait à sa façon (métadonnéesisThoughtpour Google GenAI,getReasoningContent()pour DeepSeek).- Le nouveau
OpenAiResponsesChatModelutilise l'API Responses d'OpenAI en mode stateless. - Les constructeurs et méthodes builder existants continuent de fonctionner. Le code qui lit le raisonnement doit toutefois être adapté.
- Le texte indique que Session memory persiste désormais les parts, et non plus seulement le texte.
Exemple :
ChatResponse response = chatModel.call(prompt);
// Spring AI 2.1 : un accesseur unique pour tous les chat models
List<String> thoughts = response.getResult().getOutput().getReasoning().stream()
.map(ReasoningPart::text)
.toList();
String answer = response.getResult().getOutput().getText();
Dans un projet : Si votre application utilise un modèle de raisonnement avec appels d'outils (Claude avec thinking, Gemini, OpenAI Responses), migrez vers 2.1 et remplacez les accès spécifiques au fournisseur par getReasoning(). Vérifiez aussi la persistance de l'historique, car le texte seul ne suffit plus pour rejouer le raisonnement.
Spring AI 2.1 : upsert et recherche avec vos propres embeddings
Spring Blog · 28/10/2026
En bref : Spring AI 2.1 ajoute VectorStore.upsert(...) pour indexer des documents accompagnés de vecteurs fournis par l'application, sans appel au modèle d'embedding du store. Une surcharge de similaritySearch accepte aussi un vecteur de requête. Le cas d'usage cité est la recherche multimodale (images, vidéos, audio).
Ce qu'il faut retenir :
upsert(List<EmbeddedDocument>)insère les documents aux identifiants nouveaux et remplace ceux dont l'identifiant existe déjà. Des identifiants stables, par exemple dérivés d'un SKU, évitent les doublons lors d'un ré-indexation.EmbeddedDocumentassocie unDocumentà son vecteurfloat[].- Un
Documentdoit contenir du texte ou un média, mais les vector stores ne persistent pas les médias. Le texte vide.text("")garde le document valide, etupsertne l'embedde pas. DocumentMetadata.CONTENT_REFstocke une référence externe (URL de l'image). Spring AI ne télécharge pas le contenu.similaritySearch(float[], SearchRequest)utilise le vecteur fourni et ignore le texte de la requête. Il faut utiliser le même modèle multimodal pour indexer et pour rechercher.- Les dimensions du store doivent correspondre à celles du modèle (exemple :
spring.ai.vectorstore.pgvector.dimensions=1408). La colonne vectorielle existante doit aussi avoir une dimension compatible. - Les écritures d'un même appel
upsertne sont pas transactionnelles : en cas d'erreur, certains documents peuvent déjà être écrits.
Exemple :
float[] vector = this.multimodal.call(new DocumentEmbeddingRequest(photo))
.getResult().getOutput();
Document row = Document.builder()
.id(UUID.nameUUIDFromBytes(product.sku().getBytes(UTF_8)).toString())
.text("")
.metadata(DocumentMetadata.CONTENT_REF.value(), product.photoUrl())
.metadata("sku", product.sku())
.build();
this.vectorStore.upsert(List.of(new EmbeddedDocument(row, vector)));
Dans un projet : Utilisez upsert si vos embeddings viennent d'ailleurs (API batch d'un fournisseur, migration de base, modèle multimodal) et que vous ne voulez pas les recalculer. Gardez le nom du modèle et sa version dans les métadonnées pour savoir quels documents réindexer lors d'un changement de modèle.
Transformation de requêtes dans le RAG modulaire de Spring AI
Baeldung · 30/10/2026
En bref : Le RAG modulaire de Spring AI découpe le pipeline en quatre étapes. Cet article détaille la phase de pré-récupération, où un LLM réécrit la requête utilisateur avant la recherche vectorielle. Il présente trois transformeurs fournis par Spring AI.
Ce qu'il faut retenir :
RetrievalAugmentationAdvisorrelie les étapes. Il s'enregistre sur unChatClientviadefaultAdvisors(...).- La méthode
queryTransformers(...)accepte plusieurs transformeurs. Ils s'exécutent en séquence, chacun recevant la sortie du précédent, et chacun fait son propre appel LLM via unChatClient.Builder. RewriteQueryTransformerretire les informations inutiles d'une requête longue ou confuse. Dans l'exemple, « I'm studying machine learning... What is an LLM anyway? » devient « What is an LLM in machine learning? ».TranslationQueryTransformertraduit la requête dans la langue cible, avectargetLanguage("english"), pour mieux correspondre aux documents et au modèle d'embedding.CompressionQueryTransformercompresse la requête en tenant compte de l'historique de conversation, ce qui résout les questions de suivi (« And how does it support RAG? »).- L'article recommande
temperature: 0.0pour obtenir des transformations déterministes. - La phase de récupération est configurée séparément avec
documentRetriever(VectorStoreDocumentRetriever...topK(3)).
Exemple :
RetrievalAugmentationAdvisor ragAdvisor = RetrievalAugmentationAdvisor.builder()
.queryTransformers(
RewriteQueryTransformer.builder()
.chatClientBuilder(chatClientBuilder).build(),
TranslationQueryTransformer.builder()
.chatClientBuilder(chatClientBuilder)
.targetLanguage("english").build(),
CompressionQueryTransformer.builder()
.chatClientBuilder(chatClientBuilder).build())
.documentRetriever(VectorStoreDocumentRetriever.builder()
.vectorStore(vectorStore)
.topK(3).build())
.build();
ChatClient chatClient = chatClientBuilder.defaultAdvisors(ragAdvisor).build();
Dans un projet : Ajoutez des transformeurs si vos utilisateurs posent des questions longues, dans une autre langue que vos documents, ou dans des conversations multi-tours. Chaque transformeur ajoute un appel LLM, donc une latence et un coût supplémentaires à mesurer.
Gérer les en-têtes forwarded dans Spring Boot
Baeldung · 30/10/2026
En bref : Derrière un reverse proxy ou un API gateway, l'application ne voit plus l'IP, le nom d'hôte ou le protocole du client d'origine. L'article rappelle les en-têtes X-Forwarded-* et Forwarded (RFC 7239), puis met en place un test avec Nginx et Docker. Le texte fourni s'interrompt avant la présentation détaillée des stratégies Spring Boot.
Ce qu'il faut retenir :
- En-têtes
X-Forwarded-*:For(IP client),By(IP du proxy),Host,Port,Proto(http, https, ws, wss) etPrefix(préfixe de chemin absent de l'URL backend). - En-tête standard RFC 7239 :
Forwarded: by=...; for=...; host=...; proto=.... - Les usages cités sont le rate limiting par IP, l'audit, la génération d'URL HATEOAS et les redirections HTTP.
- L'article indique que Spring Boot prend en charge trois stratégies de traitement de ces en-têtes à partir de la version 2.2.0. Le texte fourni ne les détaille pas.
- Dans la configuration Nginx de l'article, le slash final de
proxy_pass http://backend-app:8081/est obligatoire pour remplacer le préfixe/myapp/. - L'exemple utilise Spring Boot 4.1.1 et
eclipse-temurin:21-jre-alpine.
Exemple :
server {
listen 443 ssl;
server_name api.example.com;
ssl_certificate /etc/nginx/certs/api.example.com.crt;
ssl_certificate_key /etc/nginx/certs/api.example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
location /myapp/ {
proxy_pass http://backend-app:8081/;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
Dans un projet : Si votre service tourne derrière Nginx, un load balancer ou une gateway, vérifiez que les en-têtes forwarded sont transmis et pris en compte. Sans cela, les URL générées (HATEOAS, redirections) pointent vers le backend interne. Consultez l'article complet pour la propriété exacte de chaque stratégie.
This Week in Spring : nouvelles versions Spring Boot, Spring AI, Spring Security et Spring Modulith
Spring Blog · 27/10/2026
En bref : La newsletter du 27 octobre annonce plusieurs nouvelles versions. Les plus importantes sont les mises à jour de Spring Boot (corrections sur les branches 4.0 et 4.1, et première RC de la 4.2), la RC de Spring AI 2.1 et celle de Spring Security 7.2. Le texte ne mentionne aucun CVE.
Ce qu'il faut retenir :
- Spring Boot 4.0.9 et 4.1.2 sont disponibles (versions correctives), et Spring Boot 4.2.0-RC1 est publiée.
- Spring AI 2.1.0-RC1 et 2.0.2 sont disponibles. La 2.1.0-RC1 introduit les message parts et l'upsert d'embeddings détaillés dans les articles ci-dessus.
- Spring Security 7.2.0-RC1 est disponible. La newsletter cite aussi Spring Security 7.0.8 et 7.1.2, sans précision sur les corrections.
- Spring Modulith 2.2 RC1 est publiée, avec les versions 2.1.2, 2.0.9 et 1.4.14.
- Spring Cloud 2026.0.0-RC1 (Paddington) et Spring Cloud 2025.1.4 (Northfields) sont publiées, comme Spring Data 2026.0.2 et 2025.1.8.
Dans un projet : Pour les branches 4.0 et 4.1 de Spring Boot, appliquez les correctifs (4.0.9 et 4.1.2) en priorité. Testez les RC (Spring Boot 4.2, Spring AI 2.1, Spring Security 7.2) sur une branche dédiée avant de les adopter. Les notes de version contiennent les détails de migration.
Veille préparée automatiquement par Claude à partir de 7 articles de la semaine.