JAVA + SPRING AI — INTRODUCTION
Function/Tool Calling in Spring AI: Letting a Model Call Real Java Methods
The previous topic let ChatClient answer from your own documents. This topic covers a different way to extend what a single call can do: letting the model reach out and call a real Java method directly, when the answer isn’t something retrieval or the model’s own training data could ever supply on their own.
The Quick Answer
This site already has a full, dedicated explanation of what tool calling (also called function calling) is and why it matters — see Tool Calling (Function Calling): How It Actually Works if you haven’t read it, since nothing here repeats it. In one sentence, for anyone arriving fresh: tool calling lets a model produce a structured, directly executable request — a specific function name and arguments — instead of only plain text, so an application can run a real action rather than just interpret a sentence. What this topic covers is narrower and Java-specific: how Spring AI lets you turn an ordinary Java method into exactly that kind of callable tool, and how much of the request/response mechanics ChatClient handles for you automatically. The Intermediate level shows the exact annotation and a full, working @RestController example built on it.
What Spring AI Specifically Adds
Building tool calling without any framework help means writing several distinct pieces of plumbing yourself: a JSON Schema describing the tool’s name, its purpose, and the shape of its arguments, so the model has something to reason about in the first place; code that reads the model’s structured tool-call request back out and figures out which real method it corresponds to; the actual call to that method, with the model-supplied arguments correctly mapped onto its parameters; and finally, code that takes whatever that method returns and formats it in a way the model can read back in the conversation. None of that is really about yourtool’s own logic — it’s plumbing every tool-calling integration needs regardless of what the tool actually does.
Spring AI’s answer is a single method-level annotation, @Tool, plus a .tools(...) call added to the same ChatClient fluent chain the previous two topics already taught. Annotate a plain Java method, hand an instance of its class to .tools(...), and Spring AI generates the schema, watches for the model’s tool-call request, invokes the real method with the right arguments, and feeds the result back — the entire loop the previous paragraph described, without you writing any of it by hand. The Intermediate level shows exactly what that annotation looks like and exactly what that loop does underneath.
The Java Method That Learned to Answer the Phone
Picture a Java developer who already has a perfectly good method, getOrderStatus(String orderId), that looks up a real order in a real database. That method works fine when other Java code calls it directly. The problem is a model has no way to call a Java method on its own — it can only produce text. Without any help, making that method reachable from a conversation would mean the developer hand-writing a description of the method for the model to read, hand-parsing whatever structured request the model produces when it wants to use it, and hand-wiring the actual method call together — an entire second job, layered on top of a method that already did its actual job perfectly well.
Now picture that same developer with a receptionist sitting in front of that method instead. The receptionist already knows the method’s name, what it’s for, and exactly what information it needs to be called with — an order ID, nothing more. When a caller asks a question the receptionist can’t answer from memory (“what’s the status of order 4471?”), the receptionist doesn’t guess — they walk the question back to the method itself, get the real answer, and relay it back in the conversation. The developer never had to teach the receptionist how to do that; the receptionist already knew how to read the method’s own description and call it correctly.
Spring AI’s @Toolannotation is what hands that method its receptionist. The Java method itself doesn’t change at all — it’s still the exact same code that looks up a real order. What changes is that a model can now reach it, through Spring AI, without either the model or the developer having to improvise how.
Fun Fact
The Advisor that runs this entire loop underneath ChatClient, verified directly against Spring AI’s current (2.0.0) reference documentation, is called ToolCallingAdvisor — registered automatically in the same advisor chain QuestionAnswerAdvisor runs in from the previous topic. Tool calling and RAG retrieval, in other words, both plug into the exact same extension point on a ChatClientcall — the Advanced level looks at what that shared mechanism does, and doesn’t, actually mean for how the two compare. Worth flagging for anyone following an older tutorial: this auto-registration is itself new as of 2.0.0, per Spring AI’s own upgrade notes — code that already adds ToolCallingAdvisor explicitly will now have it present in the chain twice. The Intermediate level covers the dedicated property that turns auto-registration off, for anyone who needs that manual control back.
Test Yourself
What is this topic’s relationship to this site’s existing Tool Calling content (like /en/tool-calling)?
What specific problem does Spring AI’s tool-calling support solve for a Java developer?
Ready for the real mechanics — the current @Tool annotation, describing parameters with @ToolParam, registering a tool on a ChatClient call, and a real @RestControllerthat lets a model look up a real order’s status? Continue to the Intermediate level →