Choosing Between Spring AI, LangChain4j & Embabel
A concrete decision framework for three JVM AI stacks — and proof that the real answer is often 'both,' with a LangChain4j AiService and a Spring AI ChatClient living in the same application.
Three Stacks, One Codebase's Worth of Decisions
This roadmap has now built real, working code in three different frameworks: Spring AI (most of it), Embabel (a planning layer on top of Spring AI), and LangChain4j (a standalone alternative). The fraud-signals team from the last two guides still hasn't decided anything — they've seen what LangChain4j looks like next to what they already know. This guide is the actual decision.
Spring AI vs LangChain4j: A Decision Table
| Signal | Favors |
|---|---|
| Team already runs Spring Boot and wants auto-configuration, Actuator-native observability (this roadmap's production guide), and idiomatic dependency injection | Spring AI |
Need the broadest provider and vector-store coverage — 30+ EmbeddingStore implementations, more LLM providers out of the box | LangChain4j |
| Framework-agnostic requirement — Quarkus, Micronaut, or plain Java with no web framework at all | LangChain4j |
Need built-in cross-encoder re-ranking without writing your own DocumentPostProcessor | LangChain4j (ReRankingContentAggregator) |
| Want tool calling, RAG, and evaluators sharing one consistent, Spring-native mental model with everything else in the app | Spring AI |
Prefer a declarative interface (@AiService) over a fluent builder (ChatClient) as the primary programming style | LangChain4j |
| Need an MCP client/server with Spring Boot auto-configuration | Spring AI (covered in this roadmap's fourth phase; LangChain4j has MCP support too, less deeply integrated with Spring specifically) |
Neither row list is a landslide. Most teams already invested in Spring Boot — which is most of the audience for this roadmap — will find Spring AI the lower-friction default for exactly the reasons the decision table's first row describes. LangChain4j earns its place when a specific, concrete requirement (a provider Spring AI doesn't support yet, a vector store it doesn't integrate, a non-Spring runtime) points at it directly, not as a wholesale replacement chosen on vibes.
The Answer Is Often "Both"
This is the point the roadmap's own description of this phase made and this guide can now prove with real code: a Spring AI ChatClient and a LangChain4j AiService can coexist as beans in the same Spring Boot application. Say Acme Fintech's fraud-signals team wants Voyage AI's embeddings — well-supported in LangChain4j, not yet available as a Spring AI starter — while keeping the rest of their stack (the support agent, RAG, MCP, evaluators) exactly as built through the rest of this roadmap:
// build.gradle — both frameworks, same app
implementation 'org.springframework.ai:spring-ai-openai-spring-boot-starter'
implementation 'dev.langchain4j:langchain4j-voyage-ai-spring-boot4-starter'@Service
public class FraudEmbeddingService {
private final EmbeddingModel voyageEmbeddingModel; // LangChain4j bean
public FraudEmbeddingService(EmbeddingModel voyageEmbeddingModel) {
this.voyageEmbeddingModel = voyageEmbeddingModel;
}
public float[] embed(String text) {
return voyageEmbeddingModel.embed(text).content().vector();
}
}
@Service
public class SupportChatService {
private final ChatClient chatClient; // Spring AI bean, everything else in this roadmap
public SupportChatService(ChatClient.Builder builder, ChatMemory chatMemory, VectorStore vectorStore) {
this.chatClient = builder
.defaultAdvisors(
MessageChatMemoryAdvisor.builder(chatMemory).build(),
QuestionAnswerAdvisor.builder(vectorStore).build())
.build();
}
}Both starters auto-configure independently; Spring's dependency injection doesn't care which library a bean came from. FraudEmbeddingService reaches a provider Spring AI doesn't support yet; every other service in the same application keeps the Spring AI-native stack this roadmap spent six phases building. This is the practical resolution to "which framework should we use" that a pure feature comparison table can't give you: pick a primary stack for consistency, and reach for the other one, narrowly, for the specific thing it does that yours doesn't.
Where Embabel Fits Alongside Both
Embabel doesn't compete for a row in the table above — it answered a different question in the previous phase (how much should the orchestration itself be planned versus hand-written), not which model-calling library to use. It's built on Spring AI specifically, so pairing it with LangChain4j directly isn't the natural combination — if a LangChain4j-based service needs GOAP-style deterministic planning, LangChain4j's own AgenticServices.supervisorBuilder() and planBuilder() from the last guide are the more native fit, even though they take a different approach (LLM-proposed plans rather than deterministic search over typed pre/postconditions).
What's Next
Three phases, three frameworks, one consistent finding: the right choice is almost always "the smallest addition that solves an actual problem you have," not the most feature-complete option on paper. The final phase of this roadmap steps away from framework choice entirely and into production hardening — streaming, Micrometer observability, Grafana dashboards, cost control, and staying current with a fast-moving ecosystem — applied to whichever stack (or combination) this phase helped you land on.
Frequently asked questions
If I mix Spring AI and LangChain4j, do I need two separate ChatMemory implementations for the same conversation?
You'd want to, and generally should avoid needing to — mixing frameworks is best scoped to a specific capability gap (like the Voyage AI embeddings example in this guide), not spread across a single conversational flow. If both frameworks need to participate in the same conversation's memory, that's a sign the mixing has gone further than the narrow-gap-filling pattern this guide recommends.
Is switching from Spring AI to LangChain4j (or the reverse) later a realistic option if the first choice turns out wrong?
It's real work, not a config flag — ChatClient/AiServices, the tool annotations, the memory abstractions, and the RAG pipeline all differ enough that migrating means rewriting the integration layer, even though your business logic (the actual prompts, the domain records) mostly transfers. Treat the choice as consequential enough to make deliberately, using this guide's table, rather than as a reversible default.
Does Embabel work with LangChain4j at all?
Embabel is built specifically on Spring AI's abstractions, so it doesn't have a native integration with LangChain4j. A LangChain4j-based project wanting GOAP-style planning would need to either add Spring AI alongside it specifically to host Embabel, or use LangChain4j's own AgenticServices planning tools instead — mixing three frameworks for one capability is rarely the right call.
Which framework has better long-term momentum?
This roadmap deliberately doesn't answer that — it changes too fast to responsibly print an answer that stays true. Judge it yourself from current signals: release cadence on each project's GitHub, how each is evolving (Spring AI's 2.0 unifying tool calling, LangChain4j's agentic module still experimental), and which one your team's existing skills and infrastructure already lean toward.