大家好,我是Java1234_小锋老师,最近更新《2027版本 Spring AI 2.0 开发Java Agent智能体 视频教程》专辑,感谢大家支持。

本课程主要介绍和讲解Spring AI 2.0简介,Spring AI 2.0 HelloWorld搭建,Advisors --- 拦截器模式增强AI能力,对话与提示词工程(Prompt),工具调用(Function Calling / Tools) ,RAG(检索增强生成),MCP(模型 上下文协议)和多模态支持。
等这个Spring AI2.0基础课程录制完成,接下来要发布2个 企业级Java AI实战课程,RAG企业知识库系统和AI智能客服系统。大家可以点点关注,后面更精彩。
视频教程+课件+源码打包下载:
链接:https://pan.baidu.com/s/1o-zRfndo1HHrS_uFroOiCw?pwd=1234
提取码:0000
Spring AI 2.0 开发Java Agent智能体 - Advisors ------ 拦截器模式增强AI能力
Advisors 简介
Spring AI Advisors API 提供了一种灵活而强大的方式,用于拦截、修改和增强 Spring 应用程序中的 AI 驱动交互。通过利用 Advisors API,开发人员可以创建更复杂、可重用且易于维护的 AI 组件。
Spring AI 2.0 的Advisors(顾问) 本质是AI 交互的中间件 / 拦截器 ,像给 AI 聊天加了一层 "智能过滤网",能在请求发送前、响应返回后自动处理通用逻辑,让你专注于业务核心。

这个想法来自AOP(面向切面编程)。如果你学过Spring中的AOP或Filter(过滤器),那理解Advisors会觉得非常亲切。
工作原理:Advisors 如何运作?

Advisors 基于责任链模式 和AOP 面向切面编程思想,工作流程如下:
-
请求阶段:用户→ChatClient→Advisor1→Advisor2→...→LLM
-
每个 Advisor 可以修改请求(如添加历史对话、优化提示词)
-
也可以拦截请求(如发现敏感词直接返回错误)
-
-
响应阶段:LLM→AdvisorN→...→Advisor2→Advisor1→ChatClient→用户
-
每个 Advisor 可以修改响应(如格式化输出、提取关键信息)
-
也可以拦截响应(如发现不符合要求时触发重试)
-

Spring AI 2.0 提供两种核心接口:
-
CallAdvisor:处理非流式请求(一问一答)
-
StreamAdvisor:处理流式请求(边生成边返回)Spring
核心方法是nextCall()(非流式)和nextStream()(流式),通过调用这些方法将请求传递给下一个 Advisor,形成完整的处理链。
常用内置 Advisors:开箱即用的能力
Spring AI 2.0提供了一批内置的、可以直接使用的强大顾问,覆盖了最常见的AI增强需求:
| 顾问名称 | 主要作用 | 通俗解释 |
|---|---|---|
| MessageChatMemoryAdvisor | 对话记忆 | "记对话":记住用户最近说了啥,让聊天感觉是连续的 |
| PromptChatMemoryAdvisor | 提示记忆 | "提炼对话":把整个聊天记忆压缩成一个精炼的提示摘要 |
| VectorStoreChatMemoryAdvisor | 向量存储记忆 | "搜相关知识":根据用户问题,从向量数据库中找最相关的历史对话来增强记忆 |
| QuestionAnswerAdvisor | 检索增强生成 (RAG) | "查资料":先在知识库里查相关信息,再把信息"喂"给AI来回答问题] |
| SimpleLoggerAdvisor | 日志记录 | "记流水账":忠实记录下每次请求和响应的内容,方便调试和监控 |
| Semantic Cache Advisor | 语义缓存 | "聪明缓存":如果遇到意思相同的问题(而不是只字不差),可以直接返回之前缓存的答案,省时省力 |
| ToolCallAdvisor | 工具调用 | "调用外部工具":实现AI调用外部API、数据库等能力,通过递归(Recursive) 模式可以多次循环执行 |
| GuardrailsAdvisor | 安全护栏 | "安全检查":在请求到达AI前或AI响应返回前拦截不当内容 |
自定义实现Advisors
我们来实现一个自定义简单的请求和响应日志记录Advisor
第一步:新建MySimpleLoggerAdvisor类,实现CallAdvisor和StreamAdvisor接口,同时支持两种模式。
package com.java1234.advisor;
import org.springframework.ai.chat.client.ChatClientRequest;
import org.springframework.ai.chat.client.ChatClientResponse;
import org.springframework.ai.chat.client.advisor.api.CallAdvisor;
import org.springframework.ai.chat.client.advisor.api.CallAdvisorChain;
import org.springframework.ai.chat.client.advisor.api.StreamAdvisor;
import org.springframework.ai.chat.client.advisor.api.StreamAdvisorChain;
import reactor.core.publisher.Flux;
/**
* 实现CallAdvisor和StreamAdvisor接口,同时支持两种模式
*/
public class MySimpleLoggerAdvisor implements CallAdvisor, StreamAdvisor {
@Override
public ChatClientResponse adviseCall(ChatClientRequest request, CallAdvisorChain chain) {
System.out.println("发送请求:" + request);
// 调用下一个Advisor,继续处理链
ChatClientResponse response = chain.nextCall(request);
System.out.println("收到响应:" + response);
return response;
}
@Override
public Flux<ChatClientResponse> adviseStream(ChatClientRequest request, StreamAdvisorChain chain) {
System.out.println("发送流式请求:" + request);
return chain.nextStream(request)
.doOnNext(response -> System.out.println("收到流式响应片段:"+response));
}
@Override
public String getName() {
return "简单日志Advisor";
}
/**
* 这个 getOrder() 方法用于指定 Advisor(通知器)的执行顺序。
* 作用说明:
* 返回值越小,优先级越高,越早执行
* 返回 0 表示高优先级
* 如果有多个 Advisor,Spring AI 会按照此值从小到大依次执行
* @return
*/
@Override
public int getOrder() {
return 0;
}
}
第二步:AiConfiguration的ChatClient聊天客户端里,构建ChatClient的时候,添加Advisor。
@Bean
public ChatClient chatClient(OpenAiChatModel model){
return ChatClient
.builder(model) // 创建 ChatClient 对象,并设置模型为 model
.defaultAdvisors(new MySimpleLoggerAdvisor()) // 添加一个 MySimpleLoggerAdvisor,记录请求日志
.build(); // 构建 ChatClient 对象
}
最后我们来测试下:
先测试 阻塞式
http://localhost:8080/ai?question=你是谁?
控制台输出:
发送请求:ChatClientRequest[prompt=Prompt{messages=[UserMessage{content='你是谁?', metadata={messageType=USER}, messageType=USER}], modelOptions=OpenAiChatOptions: {"model":"qwen3.6-plus","streamUsage":false}}, context={}]
收到响应:ChatClientResponse[chatResponse=ChatResponse [metadata={ id: chatcmpl-005ad77a-27b5-9816-80ad-b2b269dbba56, usage: DefaultUsage{promptTokens=12, completionTokens=658, totalTokens=670}, rateLimit: { @type: org.springframework.ai.openai.metadata.OpenAiRateLimit, requestsLimit: null, requestsRemaining: null, requestsReset: null, tokensLimit: null; tokensRemaining: null; tokensReset: null } }, generations=[Generation[assistantMessage=AssistantMessage [messageType=ASSISTANT, toolCalls=[], textContent=你好!我是 Qwen(通义千问),是由阿里巴巴集团旗下通义实验室研发的大语言模型。你可以把我当作一个真诚、乐于助人的 AI 伙伴。
无论是探讨问题、寻找灵感,还是协助处理文字和逻辑任务,我都在这里。今天有什么我可以帮你的吗?, metadata={role=ASSISTANT, messageType=ASSISTANT, refusal=, finishReason=STOP, index=0, annotations=[{}], id=chatcmpl-005ad77a-27b5-9816-80ad-b2b269dbba56}], chatGenerationMetadata=DefaultChatGenerationMetadata[finishReason='STOP', filters=0, metadata=0]]]], context={}]
再测试流式的
http://localhost:8080/ai2?question=你是谁?
控制台输出:

项目里配置日志记录SimpleLoggerAdvisor
我们给项目配置下内置的SimpleLoggerAdvisor日志记录Advisor
package com.java1234.config;
import com.java1234.advisor.MySimpleLoggerAdvisor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AiConfiguration {
/**
* 创建一个 ChatClient 对象,用于处理聊天请求。
*
* @param model OpenAiChatModel 对象,用于处理聊天请求。
* @return ChatClient 对象,用于处理聊天请求。
*/
@Bean
public ChatClient chatClient(OpenAiChatModel model){
return ChatClient
.builder(model) // 创建 ChatClient 对象,并设置模型为 model
// .defaultAdvisors(new MySimpleLoggerAdvisor()) // 添加一个 MySimpleLoggerAdvisor,记录请求日志
.defaultAdvisors(new SimpleLoggerAdvisor()) // 添加一个 SimpleLoggerAdvisor,记录请求日志
.build(); // 构建 ChatClient 对象
}
/**
* 创建一个 ChatClient 对象,用于处理聊天请求。
*
* @param model OllamaChatModel 模型,用于处理聊天请求。
* @return ChatClient 模型,用于处理聊天请求。
*/
@Bean
public ChatClient chatClient2(OllamaChatModel model){
return ChatClient
.builder(model) // 创建 ChatClient 对象,并设置模型为 model
.defaultAdvisors(new SimpleLoggerAdvisor()) // 添加一个 SimpleLoggerAdvisor,记录请求日志
.build(); // 构建 ChatClient 对象
}
}
以及application.yml里面要配置下日志级别:
logging:
level:
org.springframework.ai: debug
我们来测试下:
http://localhost:8080/ai?question=你是谁?
控制台日志输出,请求和响应都有完整的数据显示
2026-04-25T14:33:37.198+08:00 DEBUG 49764 --- [helloWorld] [nio-8080-exec-3] o.s.a.c.c.advisor.SimpleLoggerAdvisor : request: ChatClientRequest[prompt=Prompt{messages=[UserMessage{content='你是谁?', metadata={messageType=USER}, messageType=USER}], modelOptions=OpenAiChatOptions: {"model":"qwen3.6-plus","streamUsage":false}}, context={}]
2026-04-25T14:33:43.232+08:00 DEBUG 49764 --- [helloWorld] [nio-8080-exec-3] o.s.a.c.c.advisor.SimpleLoggerAdvisor : response: {
"metadata" : {
"empty" : false,
"id" : "chatcmpl-795a2d7a-ee98-9612-bb6f-0a1f741b5416",
"model" : "qwen3.6-plus",
"promptMetadata" : [ ],
"rateLimit" : {
"requestsLimit" : null,
"requestsRemaining" : null,
"requestsReset" : null,
"tokensLimit" : null,
"tokensRemaining" : null,
"tokensReset" : null
},
"usage" : {
"promptTokens" : 12,
"completionTokens" : 267,
"totalTokens" : 279,
"nativeUsage" : {
"completion_tokens" : 267,
"prompt_tokens" : 12,
"total_tokens" : 279,
"prompt_tokens_details" : { },
"completion_tokens_details" : {
"reasoning_tokens" : 236
}
}
}
},
"result" : {
"metadata" : {
"contentFilters" : [ ],
"empty" : true,
"finishReason" : "STOP"
},
"output" : {
"media" : [ ],
"messageType" : "ASSISTANT",
"metadata" : {
"role" : "ASSISTANT",
"messageType" : "ASSISTANT",
"finishReason" : "STOP",
"refusal" : "",
"index" : 0,
"annotations" : [ { } ],
"id" : "chatcmpl-795a2d7a-ee98-9612-bb6f-0a1f741b5416"
},
"text" : "我是 Qwen(通义千问),由阿里巴巴集团旗下通义实验室自主研发的大语言模型。有什么我可以帮你的吗?",
"toolCalls" : [ ]
}
},
"results" : [ {
"metadata" : {
"contentFilters" : [ ],
"empty" : true,
"finishReason" : "STOP"
},
"output" : {
"media" : [ ],
"messageType" : "ASSISTANT",
"metadata" : {
"role" : "ASSISTANT",
"messageType" : "ASSISTANT",
"finishReason" : "STOP",
"refusal" : "",
"index" : 0,
"annotations" : [ { } ],
"id" : "chatcmpl-795a2d7a-ee98-9612-bb6f-0a1f741b5416"
},
"text" : "我是 Qwen(通义千问),由阿里巴巴集团旗下通义实验室自主研发的大语言模型。有什么我可以帮你的吗?",
"toolCalls" : [ ]
}
} ]
}