Writing Custom Advisors in Spring AI 2.0: Logging, PII Redaction and Token Budgets
Write Spring AI 2.0 advisors for logging, PII redaction and token budgets, and learn why advisor order and streaming decide what your logs and memory see.
Write Spring AI 2.0 advisors for logging, PII redaction and token budgets, and learn why advisor order and streaming decide what your logs and memory see.
A chat model forgets everything between calls. This article shows how Spring AI 2.0 chat memory works, and what its JDBC and Redis repositories, the message window, and concurrent requests do that the defaults do not tell you, run against real PostgreSQL 16 and Redis Stack.
JDK 27 makes compact object headers and G1 the defaults everywhere. Measured on a Spring Boot 4.1 service with JDK 25, 26 and 27: 15% smaller live set, which classes shrink, real cgroup container sizing, and the flags that stopped working.
Java's LazyConstant (JEP 531, third preview in JDK 27) against the holder idiom and double-checked locking: the API run on JDK 25, 26 and 27, the failure rule that changed between 26 and 27, List, Map and Set.ofLazy, a JMH benchmark, and why it is not yet for shipped code.
Sealed classes and interfaces in Java, verified on JDK 21, 25 and 27: permits and the three modifiers, six compile errors, why an exhaustive switch should have no default, generic and recursive hierarchies, the visitor comparison, JVM enforcement, modules, and Jackson 3 polymorphism.
Java pattern matching from JDK 21 to 27, verified on three JDKs: type patterns, switch guards, record patterns, sealed exhaustiveness and the MatchException that separate compilation can still cause, null and unnamed patterns, and JEP 532 primitive patterns (preview).
Java 25 finalizes JEP 511: import module java.base; replaces a page of imports. See what it does, which imports win when names clash, why import module java.sql does not give you java.base, why java.se needs --add-modules, and when to use it.
Java 25 finalizes JEP 513: statements before super() or this(). See the old error and workaround, validation and argument preparation, the parent-calls-child bug it fixes, and the compile errors that remain, with JDK 25 and 27 wordings compared.
Java 25 finalizes JEP 512: void main() in a file with no class, the java.lang.IO helper, implicit java.base imports, the measured launcher order, and a private-constructor difference between JDK 25 and 27 — every claim compiled and run, with transcripts.
Spring Boot 4 i18n with MessageSource and LocaleResolver: Marathi and Hindi bundles, Accept-Language vs a cookie, MessageFormat apostrophes and digits, and localized validation and ProblemDetail.