Choosing a Java LLM Integration Strategy in 2026: Spring AI 1.1 vs LangChain4j vs Direct API Calls
Three genuinely different architectural postures — and a practical framework to help your team choose the right one before you build the wrong thing.
1. Why This Decision Matters Now
A year ago, “Java AI integration” meant writing an OpenAI wrapper and calling it a day. In 2026, that choice has become a genuine architectural decision — and making the wrong one early is expensive to undo.
The Java LLM ecosystem matured quickly and simultaneously from multiple directions. Spring AI 1.0 shipped in May 2025, followed by a substantial 1.1 release in November with full Model Context Protocol integration, 20+ model backends, and a structured Advisors API. LangChain4j reached its 1.0 stable milestone at almost exactly the same time, bringing a completely different philosophy: framework-agnostic, modular, and deliberately unopinionated about your deployment model. And Java’s own built-in HttpClient, strengthened further by JEP 517’s HTTP/3 support in JDK 26, means raw API calls are more viable than ever for teams with simple requirements.
All three options are production-ready. All three are actively maintained. And they represent fundamentally different bets about how AI will be integrated into your services over the next three to five years. The choice is not about which one is best in the abstract — it is about which architectural posture fits your team, your stack, and your workload. That is what this article helps you reason through.
2. The Three Architectural Postures
Before comparing features and API surfaces, it helps to name the underlying architectural posture each option represents. They are genuinely different, and the differences matter more than any individual feature comparison.
| Option | What it represents | Best for | What you trade |
|---|---|---|---|
| Spring AI 1.1 | The Platform Bet — opinionated, full-stack AI platform, deeply Spring Boot-native | Spring Boot teams wanting auto-config, MCP, Advisors, and 20+ providers in one coherent system | Flexibility, for velocity and ecosystem coherence |
| LangChain4j | The Toolbox Bet — modular library, works with Spring, Quarkus, Micronaut, or plain Java | Non-Spring shops, polyglot stacks, or teams wanting granular control over composition | Some convenience, for portability and granular control |
| Direct API | The Minimal Bet — call provider APIs via HttpClient or official SDK, no AI framework dependency | Bounded, one-shot integrations with no plans for growth into agents or RAG | Capability, for simplicity and zero abstraction over |
3. Spring AI 1.1: The Integrated Platform
Spring AI began life as an experimental project in 2023 and reached production-grade 1.0 status in May 2025. The 1.1 release that followed in November 2025 added what many teams were waiting for: full Model Context Protocol (MCP) integration, a structured Advisors API for RAG pipelines and conversation memory, and support for over 20 AI model providers. The 1.1 development cycle accumulated over 850 improvements — a pace that signals a team executing a clear roadmap, not reacting to feature requests.
The core value proposition of Spring AI is Spring-native coherence. If your team is already comfortable with @Service, @Bean, Spring Boot auto-configuration, and Spring’s observability stack, Spring AI feels like an extension of what you already know. Tool calling works by annotating existing Spring beans — there is no separate registration step. Chat memory can be backed by any Spring Data-compatible store. RAG pipelines compose through the Advisors API using familiar patterns.
As one analyst described it following the Spring I/O 2025 conference: for the first time, Java developers can build AI agents that feel genuinely native — no Python sidecar, no LangChain wrapper, no second deployment. That framing is accurate as far as it goes for Spring shops — but it does assume you want the Spring model to extend into your AI layer, which is the right assumption for most enterprise Java teams and the wrong one for others.
Spring AI 1.1 — ChatClient with tool calling
@Service
public class ProductAdvisorService {
private final ChatClient chatClient;
public ProductAdvisorService(ChatClient.Builder builder,
ProductRepository products) {
this.chatClient = builder
.defaultSystem("You are a helpful product advisor.")
.defaultTools(products) // Spring @Service becomes a tool
.defaultAdvisors(
new MessageChatMemoryAdvisor(new InMemoryChatMemory()),
new QuestionAnswerAdvisor(vectorStore)
)
.build();
}
public String advise(String question, String sessionId) {
return chatClient.prompt()
.user(question)
.advisors(a -> a.param(CHAT_MEMORY_CONVERSATION_ID_KEY, sessionId))
.call()
.content();
}
}
The MCP integration deserves particular attention. Spring AI 1.1 ships both an MCP server and client, meaning a Spring Boot application can expose its own business logic as MCP-compliant tools — callable by any MCP-compatible agent, not just Spring AI itself. The transport supports Streamable HTTP (the modern standard), SSE for backward compatibility, and stdio for local process tools. For teams building agent-to-agent or multi-model workflows, this is a significant capability shipped with zero additional infrastructure.
Spring AI 2.0 Is Already in Milestones: Spring AI 2.0.0-M2 was announced in January 2026, built on Spring Boot 4 foundations. It introduces full JSpecify null-safety annotations across the API, enforced at compile time with NullAway. For Kotlin users, this translates to true nullable types. If you’re starting a new project today, the 1.1 series is the stable choice — but awareness of the 2.0 migration path is worth factoring into your dependency strategy.
4. LangChain4j: The Independent Toolbox
LangChain4j was created in early 2023 by Dmytro Liubarskyi, and its defining design principle — stated clearly and maintained consistently — is that it should feel native to Java developers regardless of which framework they are using. Smooth integration is made possible through Quarkus, Spring Boot, and Helidon integrations, but none of these is required. LangChain4j works as a plain library. That distinction matters more than it might first appear.
Where Spring AI is opinionated about composition (Advisors, Spring Beans as tools, Spring Boot lifecycle), LangChain4j is opinionated about building blocks. It gives you DocumentLoader, DocumentSplitter, EmbeddingStore, ChatMemory, and AiServices as independent components. You assemble them. This Lego approach — as the community commonly describes it — offers more granular control than Spring AI without framework lock-in. It also means you shoulder more responsibility for architectural decisions, because LangChain4j does not make them for you.
As of early 2026, LangChain4j is at version 1.10.x, having shipped a rapid series of monthly releases since its 1.0 stabilisation in May 2025. The AiServices abstraction — which generates a Java interface implementation from annotated method signatures — remains its most distinctive feature: you describe what you want the AI to do in a typed interface, and LangChain4j generates the prompt, handles the conversation, calls tools, and parses the output.
LangChain4j — AiServices with typed interface
import dev.langchain4j.service.*;
import dev.langchain4j.agent.tool.Tool;
// 1. Declare what you want — typed, inspectable, testable
interface ProductAdvisor {
@SystemMessage("You are a helpful product advisor.")
@UserMessage("{{question}}")
String advise(@V("question") String question);
}
// 2. Register tools as plain annotated methods
class ProductTools {
@Tool("Look up a product by SKU")
public Product getProduct(String sku) {
return productRepo.findBySku(sku);
}
}
// 3. Wire together — works with Spring, Quarkus, or plain Java
ProductAdvisor advisor = AiServices.builder(ProductAdvisor.class)
.chatLanguageModel(
OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-4o-mini")
.build()
)
.chatMemory(MessageWindowChatMemory.withMaxMessages(20))
.tools(new ProductTools())
.build();
String answer = advisor.advise("What colours is SKU-9921 available in?");
LangChain4j’s framework-agnostic nature makes it the natural choice for teams running Quarkus (where the Quarkiverse extension provides deep CDI integration), Micronaut (which added LangChain4j 1.5.0 support in Micronaut 4.10.0), or genuinely polyglot shops that maintain services on multiple frameworks. It is also the better fit for teams that want to upgrade their AI layer independently of their web framework — a real operational concern in organisations where framework upgrades require change control processes.
LangChain4j in Production Already: LangChain4j is in production use at MuleSoft by Salesforce, Deutsche Telekom’s Advanced Coding Assistant, Apache Camel, MicroProfile, and WildFly. The community of 200+ contributors includes engineers from Google, Red Hat, and JetBrains. This is not an experimental library.
5. Direct API Calls: The Minimal Bet
The direct API approach is not a fallback for teams that haven’t heard of the alternatives. It is a deliberate architectural choice with a specific use-case profile: you have a bounded, well-defined integration need, your LLM usage is likely to remain simple, and you want zero abstraction layer between your code and the provider’s API.
All major LLM providers — OpenAI, Anthropic, Google, Azure OpenAI — now publish official Java SDKs on Maven Central. OpenAI’s official Java SDK reached production quality in 2025 and is notably the one that Spring AI 1.1.1 integrated with natively, thanks to a contribution from Microsoft’s Julien Dubois. This means a direct SDK call and a Spring AI call can share the same underlying HTTP implementation if you choose.
Direct API — OpenAI Java SDK (no framework dependency)
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.chat.completions.*;
OpenAIClient client = OpenAIOkHttpClient.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.build();
ChatCompletion completion = client.chat().completions().create(
ChatCompletionCreateParams.builder()
.model("gpt-4o-mini")
.addSystemMessage("You are a concise support assistant.")
.addUserMessage("How do I reset my password?")
.maxCompletionTokens(200)
.build()
);
String reply = completion.choices().get(0)
.message().content().orElse("");
System.out.println(reply);
The trade-off is straightforward: you get maximum transparency, minimum dependencies, and a learning surface that is just the provider’s API reference. What you give up is everything that frameworks provide above the API level — abstraction over multiple providers, conversation memory management, vector store integration, RAG pipelines, streaming helpers, structured output parsing, and observability hooks. Every one of those things you will have to implement yourself, or bolt on separately, as requirements grow.
Consequently, the direct approach is well-suited for three specific profiles: serverless functions with a single LLM call per invocation, microservices that need one specific capability (classification, extraction, summarisation) with no conversational context, and teams doing exploratory integration work before committing to a framework. It is poorly suited for any use case that will grow into multi-step workflows, RAG, agents, or multi-model routing — which is most production AI features after the first six months.
6. Feature Comparison at a Glance
| Capability | Spring AI 1.1 | LangChain4j 1.x | Direct API |
|---|---|---|---|
| Framework dependency | Spring Boot | None required | None |
| Model provider support | 20+ providers | 20+ providers | One per SDK |
| RAG pipeline | Advisors API | Modular toolbox | DIY |
| Conversation memory | Built-in advisors | ChatMemory API | DIY |
| Tool / function calling | @Bean as tools | @Tool annotation | Manual JSON |
| MCP support | Full (client + server) | MCP client | None |
| Vector store integration | 15+ stores | 30+ stores | DIY |
| Structured output | Native (1.1.1) | OutputParser API | Manual parsing |
| Observability / tracing | Micrometer native | OTel via Quarkus/CDI | Manual |
| Streaming responses | Reactor Flux | TokenStream API | SSE / manual |
| Quarkus / Micronaut support | Spring Boot only | Native extensions | Any framework |
| Setup complexity | Low (Spring auto-config) | Low-medium | Minimal |
| Growth ceiling | Very high | Very high | Low |
7. Latency, Overhead, and Real Costs
A concern that surfaces regularly in architectural discussions is abstraction overhead: how much latency do these frameworks add compared to raw HTTP calls? The short answer is that, for LLM workloads, framework overhead is almost entirely irrelevant — and understanding why shapes the decision well.
Where Time Actually Goes in a Typical LLM Request

The chart is consistent with what teams report in production: an LLM API call takes 500–3000ms depending on model, token count, and provider load. Framework overhead — the cost of Spring AI’s Advisor chain, LangChain4j’s AiServices proxy, or your own HTTP client wrapper — is measured in single-digit milliseconds at most. It is not a factor in the decision.
What does affect cost and performance in practice is token efficiency. Frameworks that add system prompt boilerplate or memory context to every request can meaningfully increase input token counts. Spring AI’s conversation memory advisors and LangChain4j’s chat memory both handle this by windowing or summarising history — but the default configuration varies between them. Before deploying either to production with high conversation volume, review what context each framework appends automatically and whether it matches your token budget.
Token Efficiency Matters More Than Framework Speed: At $0.55 per million input tokens for gpt-4o-mini (the cheapest capable model as of early 2026), an unnecessary 500-token system context injected on every request costs $0.000275 per call. At 100,000 daily calls, that is $27.50/day — $10,000/year — from a single misconfigured default. Profile your token usage before you optimise for latency.
8. The Decision Framework
Rather than a recommendation that pretends to apply universally, here is a set of conditions that reliably map to each choice. Work through them in order — the first one that matches your situation is likely the right answer.
| Option | What it represents | Best for | What you trade |
|---|---|---|---|
| Spring AI 1.1 | The Platform Bet — opinionated, full-stack AI platform, deeply Spring Boot-native | Spring Boot teams wanting auto-config, MCP, Advisors, and 20+ providers in one coherent system | Flexibility, for velocity and ecosystem coherence |
| LangChain4j | The Toolbox Bet — modular library, works with Spring, Quarkus, Micronaut, or plain Java | Non-Spring shops, polyglot stacks, or teams wanting granular control over composition | Some convenience, for portability and granular control |
| Direct API | The Minimal Bet — call provider APIs via HttpClient or official SDK, no AI framework dependency | Bounded, one-shot integrations with no plans for growth into agents or RAG | Capability, for simplicity and zero abstraction over |
9. Three Anti-Patterns to Avoid
The Java LLM ecosystem is new enough that teams are still developing institutional knowledge about what works and what doesn’t. Here are three patterns that appear reasonable upfront and prove costly over time.
9.1 Anti-pattern 1: Starting Direct and Planning to Migrate Later
Direct API calls are fast to start and easy to reason about. They are also significantly harder to migrate away from than adopting a framework from the beginning. The migration tax is not just about changing the HTTP layer — it is about the conversation history your application no longer tracks, the RAG pipeline you never built, and the observability gaps you discover in production. If your feature has any chance of growing into agents, multi-turn conversations, or RAG, it is almost always cheaper to start with a framework than to migrate a direct integration after three months in production.
9.2 Anti-pattern 2: Using Spring AI in a Non-Spring Service
Spring AI’s auto-configuration, lifecycle management, and Advisor API are tightly coupled to the Spring ApplicationContext. Attempting to use Spring AI without Spring Boot — for example, in a Quarkus service or a standalone Java process — produces confusing dependency tangles and fails to benefit from any of Spring AI’s ergonomics. LangChain4j exists precisely for these situations. Use it.
9.3 Anti-pattern 3: Treating Framework Abstractions as Portability Guarantees
Both Spring AI and LangChain4j present a unified interface over multiple LLM providers. It is tempting to interpret this as “you can swap providers without changing your application code.” In practice, model behaviour is not abstracted away. A prompt tuned for GPT-4o produces different outputs when sent to Claude Sonnet or Gemini Pro. Tool call schemas are handled differently by different providers. Streaming behaviour varies. The framework provides a syntactic abstraction, not a semantic one. Build for one primary provider; maintain explicit test coverage for any alternative you plan to support.
The Most Common Real-World Mistake: Underestimating how quickly simple features grow. A one-shot summarisation endpoint becomes stateful chat by month two, gains tool calling by month four, and gets a RAG pipeline by month six. Every team that started with direct API calls and hit this trajectory had to either stop feature delivery to migrate the integration layer, or live with a patchwork of half-abstracted LLM calls indefinitely. Choose your framework before you need it, not after.
10. What We Have Learned
Java’s LLM integration landscape is mature enough to treat as a real architectural decision — and too varied to resolve with a single universal recommendation. Here is the distilled version:
- Spring AI 1.1 (November 2025) is the right choice for Spring Boot teams. Full MCP integration, 20+ providers, Advisors API for RAG and memory, and Spring 2.0 on the horizon make it the most complete platform for the Spring ecosystem.
- LangChain4j 1.x is the right choice for non-Spring teams, polyglot shops, or teams that want to own their composition. Its 30+ vector store integrations, AiServices abstraction, and native Quarkus/Micronaut extensions make it the most flexible option.
- Direct API calls are appropriate only for bounded, one-shot integrations with no plans for growth. Start here only if you genuinely will not need conversation, RAG, or tool calling — and be honest about how likely that is to stay true.
- Framework overhead does not matter for LLM workloads. LLM network latency dwarfs any Java abstraction cost by two to three orders of magnitude.
- Token usage does matter. Profile what context your chosen framework appends to every request before scaling to production volume.
- Provider portability is syntactic, not semantic. Do not assume swapping an OpenAI model for an Anthropic one is a one-line change — it requires prompt re-evaluation and test coverage.
- Migration cost is asymmetric. Going from a framework to direct calls is trivial; going from direct calls to a framework is a significant integration rewrite. Bias toward adopting a framework earlier than you think you need it.





