Enterprise Java

Spring Boot 4, Spring AI, and AI-First Java Development

Jakarta EE 11, built-in API versioning, full modularisation, and LLM integration are all here now. Not on a roadmap — shipped. Here’s the complete picture.

November 2025 was not a quiet month for Java. Spring Boot 4.0.0 went live on Maven Central on November 20th — the most significant major release since Spring Boot 3 arrived in 2022. Beneath it sat a fully updated Spring Framework 7, and alongside it, a maturing Spring AI ecosystem that had reached 1.0 GA six months earlier and was already heading toward 2.0. Together, these releases mark a genuine generational shift — not a marketing phrase, but a structural one. The foundations change here.

Moreover, this release is not incremental. Spring Boot 4 drops Jackson 2, removes JUnit 4 support entirely, eliminates Undertow, and breaks several long-standing configuration patterns. At the same time, it delivers things Java developers have wanted for years: first-class API versioning, built-in retry and concurrency limits, a coherent null safety story, and LLM integration that feels native to the Spring programming model. So let’s walk through it all, feature by feature, clearly and without exaggeration.

1. Jakarta EE 11 — The Namespace Migration Completes

Spring Boot 3 already made the leap from javax.* to jakarta.* packages — a change that caused significant migration pain when it landed in 2022. Spring Boot 4 moves the Jakarta EE baseline from version 9 to version 11, which is a less traumatic jump but still brings meaningful updates to the specifications your code depends on.

Specifically, this brings Jakarta Servlet 6.1Jakarta Persistence 3.2Jakarta Bean Validation 3.1, and Jakarta WebSocket 2.2. On the persistence side, Hibernate ORM 7.1 is now the managed version, and notably it no longer allows detached entities to be silently reassociated with a persistence context — a change that can surface hidden bugs in existing applications if you’ve been relying on that lenient behaviour. Furthermore, Undertow has been removed entirely because it isn’t yet compatible with Servlet 6.1. If your application uses Undertow as its embedded container, migration to Tomcat 11 or Jetty 12.1 is required before upgrading.

Breaking Changes to Know Before Upgrading

Jackson 2.x support is gone — you’ll need Jackson 3.x. JUnit 4 is entirely removed in favour of JUnit Jupiter (JUnit 5). Undertow is no longer supported. All Spring Boot 3 deprecations have been removed, so clean those up first in 3.5 before touching 4.0. The Spring team strongly recommends upgrading to Spring Boot 3.5 first, resolving all deprecation warnings, and only then migrating to 4.0.

2. Modularisation — Saying Goodbye to the Monolith JAR

If you’ve ever looked at the classpath of a Spring Boot 3 application and winced at how much of spring-boot-autoconfigure was loaded for things you don’t use, Spring Boot 4 addresses this directly. The entire codebase has been split into 70+ focused modules. Each technology integration now has its own dedicated module and starter, rather than everything being bundled into two enormous JARs.

In practical terms, this means faster builds, smaller native images, and IDE auto-complete that no longer suggests configuration properties from technologies you never included. The change also improves GraalVM AOT processing — with fewer unused classes in the metadata graph, native compilation is both faster and produces smaller outputs. Additionally, the new @ConfigurationPropertiesSource annotation helps modular projects generate complete configuration metadata even when types live in separate modules at build time.

pom.xml — Spring Boot 4 migration snippet

<!-- Spring Boot 3 — monolithic starter -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Spring Boot 4 — explicit modular starters -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-webmvc</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-jackson</artifactId>
</dependency>

<!-- Classic starter available for gradual migration -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-classic</artifactId>
</dependency>

3. Built-In API Versioning — Finally

This is the feature that generated the most excitement in the community — and rightly so. For years, API versioning in Spring was a DIY exercise. You either duplicated your controllers under different URL paths (/api/v1/orders/api/v2/orders), wrote custom RequestCondition implementations, or pulled in a third-party library. Spring Framework 7 makes versioning a first-class citizen, available in both Spring MVC and Spring WebFlux.

The framework now supports four versioning strategies: path segment, HTTP header, query parameter, and media type. You configure the strategy once, then annotate your mappings with a version attribute. Spring handles the routing automatically. Equally important, there is built-in deprecation handling compliant with RFC 9745 — the standard for deprecating HTTP APIs — so you can mark old versions as sunset without any custom filter code.

OrderController.java — Native API versioning in Spring Boot 4

// application.properties — choose your versioning strategy
spring.mvc.apiversion.use-header=X-API-Version
// or: spring.mvc.apiversion.use-path-segment=1
// or: spring.mvc.apiversion.use-media-type=true

@RestController
@RequestMapping("/api/orders")
public class OrderController {

  @GetMapping(path = "/{id}", version = "1.0")
  public OrderV1 getOrderV1(@PathVariable String id) { ... }

  // Version 2.0 — same path, Spring routes automatically
  @GetMapping(path = "/{id}", version = "2.0")
  public OrderV2 getOrderV2(@PathVariable String id) { ... }

  // Mark old version as sunset — RFC 9745 compliant headers sent
  @GetMapping(path = "/{id}", version = "0.9", deprecated = true)
  public OrderLegacy getLegacy(@PathVariable String id) { ... }
}

4. JSpecify Null Safety — Null Pointers Get Harder to Hide

Java’s relationship with null has always been fraught. Every project has its own mix of @Nonnull@Nullable@NotNull, and similar annotations from different libraries — none of them interoperable. Spring Framework 7 adopts JSpecify as the single standard for null safety across the entire Spring portfolio. The JSpecify collective includes OpenJDK, Broadcom, Google, JetBrains, and Sonar, which means the tooling support is genuinely good.

In practice, this means @NonNull and @Nullable from org.jspecify.annotations are now the annotations you’ll see throughout Spring’s own APIs. Kotlin 2.2 (which is the new baseline for Kotlin in Spring Boot 4) automatically translates JSpecify annotations into Kotlin nullability, meaning you get type-safe null handling at the language level rather than just at the IDE hint level. IntelliJ IDEA 2025.3 ships full support for JSpecify-based data flow analysis. Consequently, null pointer exceptions that were previously silent at compile time now surface as warnings or errors much earlier in the development cycle.

5. Built-In Resilience — @Retryable and @ConcurrencyLimit

Previously, retry logic in Spring applications required pulling in the separate spring-retry library and adding @EnableRetry to a configuration class. Spring Framework 7 moves retry and concurrency control directly into the core context. The @Retryable annotation now works out of the box, supports exponential back-off and jitter configuration, and automatically adapts to reactive methods when used in a WebFlux context. The companion @ConcurrencyLimit annotation implements the bulkhead pattern, capping the number of concurrent invocations of a method — particularly useful alongside virtual threads, where the risk of overwhelming downstream services increases because the JVM no longer applies natural backpressure through thread pool exhaustion.

Spring Boot 4 — Feature Maturity at Launch

Qualitative maturity rating (0–100) of key Spring Boot 4 features based on documentation depth, community adoption signals, and framework completeness. Source: author assessment of official release notes.

6. Spring AI — LLMs as First-Class Spring Beans

While Spring Boot 4 was the headline, the most strategically important shift in the Java ecosystem over the past eighteen months has been Spring AI reaching production readiness. Spring AI 1.0 went GA in May 2025. By the end of 2025, it had become the richest LLM integration framework on the JVM, and version 2.0 was already in milestone builds.

The core design principle of Spring AI is familiar to any Spring developer: model-agnostic abstractions, auto-configuration, and Spring Boot starters. You select an AI provider — OpenAI, Anthropic, Google Gemini, Azure OpenAI, Amazon Bedrock, Ollama, Mistral, and others — add the corresponding starter dependency, provide an API key in your properties file, and inject a ChatClient or ChatModel bean exactly as you would any other Spring-managed dependency. Switching providers is a matter of changing your dependency and properties, not rewriting application code.

6.1 RAG — Retrieval-Augmented Generation in Java

One of the most practically useful patterns in enterprise AI is Retrieval-Augmented Generation (RAG): rather than relying solely on the LLM’s training data, you retrieve relevant documents from your own data stores and include them in the prompt context. Spring AI’s Advisors API makes this pattern declarative. The framework ships with auto-configuration for Apache Cassandra, MongoDB Atlas, PostgreSQL with pgvector, Redis, Pinecone, Qdrant, Milvus, Weaviate, Chroma, and others as vector stores. The ETL framework handles document ingestion from S3, local file systems, MongoDB, and other sources, with PDF chunking via Apache Tika. For long-running conversations, the memory management features include compaction and retention policies.

“Spring AI applies familiar Spring ecosystem design principles — portability, modularity, and POJOs — to AI domain challenges. The goal is to make AI integration feel native to the Java developer, not a Python port.”— Spring AI design philosophy, spring.io/projects/spring-ai

6.2 Tool Calling and MCP — Agents That Do Things

Beyond text generation, the most significant capability Spring AI provides is Tool Calling (also called Function Calling). This allows an LLM to invoke your Spring-managed methods at runtime when it decides additional context or action is needed. You annotate a method with @Tool, register it with the ChatClient, and the LLM can call it — Spring AI handles the JSON schema generation, the invocation, and the result injection back into the conversation context. Furthermore, Spring AI has integrated the Model Context Protocol (MCP) — the standard protocol for connecting AI models to data sources and tools — both as an MCP client and as an MCP server. This means your Spring AI application can expose its tools to any MCP-compatible agent, or consume tools from any external MCP server.

ChatService.java — Tool calling + RAG with Spring AI

@Service
public class ProductAssistant {

  private final ChatClient chatClient;

  public ProductAssistant(ChatClient.Builder builder,
                          VectorStore vectorStore) {
    this.chatClient = builder
      .defaultAdvisors(
        new QuestionAnswerAdvisor(vectorStore), // RAG
        new MessageChatMemoryAdvisor(new InMemoryChatMemory()) // memory
      )
      .build();
  }

  // Annotated method — LLM can invoke this as a tool
  @Tool(description = "Look up current stock level for a product SKU")
  public int checkStock(String sku) {
    return inventoryService.getStock(sku);
  }

  public String ask(String question) {
    return chatClient.prompt()
      .user(question)
      .tools(this)        // register tools from this bean
      .call()
      .content();
  }
}

7. Spring Boot 4 vs. 3.x — What Changed Where

FeatureSpring Boot 3.xSpring Boot 4.0
Jakarta EEEE 9 / EE 10EE 11 (Servlet 6.1, JPA 3.2)
API VersioningManual / DIYBuilt-in (path, header, query, media type)
Null SafetyMixed annotationsJSpecify portfolio-wide
Retry / BulkheadExternal spring-retryBuilt-in @Retryable, @ConcurrencyLimit
ModularisationMonolithic autoconfigure JAR70+ focused modules
JacksonJackson 2.xJackson 3.x required
JUnitJUnit 4 + JUnit 5JUnit Jupiter only
UndertowSupportedRemoved (Servlet 6.1 incompatible)
KotlinKotlin 1.x / 2.0Kotlin 2.2 baseline
GraalVMGraalVM 23+GraalVM 25 required

8. Spring AI — Provider & Vector Store Coverage

Spring AI 1.0 GA — Supported AI Providers vs. Vector Stores

Counts of officially auto-configured integrations in Spring AI 1.0 GA. Source: spring.io/projects/spring-ai and Spring AI GitHub.

9. The Migration Path — Where to Start

The Spring team is clear on the recommended path: get to Spring Boot 3.5 first. That means fixing every deprecation warning in your current codebase before you touch the 4.0 migration. Any deprecated API that survived into 3.5 is gone in 4.0 with no fallback. Once you’re clean on 3.5, the jump to 4.0 is primarily about three things: updating your starters to the new modular names (classic starters are available as a bridge), migrating from Jackson 2 to Jackson 3, and removing any remaining javax.* imports that might have slipped through the Boot 3 migration.

For Spring AI specifically, the quickest entry point is start.spring.io, which now surfaces all AI provider starters and vector store options in the dependency selector. You pick your model provider, pick your vector store if needed, and the Initializr generates a project with the correct dependencies and auto-configuration already wired. From there, you need an API key in your properties file and a ChatClient injection to make your first LLM call.

Spring AI Framework Support Matrix (March 2026)

Spring Boot 3.3+ — Spring AI 1.0 GA fully supported. Spring Boot 4.0 — Spring AI 2.0 milestone compatible; GA expected mid-2026. Spring Cloud, Spring Modulith 2.0, Spring Security 7, and Spring Batch 6 all shipped Spring Boot 4 compatible GA versions alongside the Boot 4 release. Spring AI 2.0 GA is the one remaining holdout on the Boot 4 train.

10. What We’ve Learned

Spring Boot 4, released November 20, 2025, is the most structurally significant Spring release since the move to Jakarta EE in 2022. It delivers Jakarta EE 11, a fully modularised codebase across 70+ focused modules, native API versioning for both MVC and WebFlux, JSpecify null safety across the entire portfolio, and first-class support for Java 25 — all while keeping a Java 17 minimum for existing applications.

Breaking changes are real: Jackson 3 is required, JUnit 4 is gone, Undertow is removed, and all Spring Boot 3 deprecations have been cleared out. The migration path is upgrade to 3.5 first, clean up deprecations, then move to 4.0. Classic starters bridge the modularisation gap for teams that need a gradual transition.

Alongside Boot 4, Spring AI has matured into a production-ready LLM integration layer for enterprise Java. With model-agnostic abstractions, RAG pipelines, tool calling, MCP support, and auto-configuration for 10+ vector stores, it brings the patterns that Python’s LangChain pioneered directly into the Spring programming model — with the type safety and observability that Java teams expect. Spring AI 2.0 GA, targeting Spring Boot 4 compatibility, is the next milestone to watch.

Eleftheria Drosopoulou

Eleftheria is an Experienced Business Analyst with a robust background in the computer software industry. Proficient in Computer Software Training, Digital Marketing, HTML Scripting, and Microsoft Office, they bring a wealth of technical skills to the table. Additionally, she has a love for writing articles on various tech subjects, showcasing a talent for translating complex concepts into accessible content.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Back to top button