1.创建一个基础项目

2.创建父子工程
2.1 父工程中引入spring boot
在父工程的pom文件中引入 spring-boot-starter-parent 。(也就是引入spring boot)
因为后续我引入的是spring-ai-bom 版本是2.0.1,所以我就引入4.1.1版本的spring boot。大家看完文章之后可以使用其他版本的spring ai看看有什么区别。

<!-- 加入spring boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>4.1.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
注意,我们后续将要引入 spring-ai-bom,这个依赖的每个版本,可能需要的spring boot版本要求是不一样的。例:Spring AI 2.0.x与Spring AI 1.1.8 它们分别支持的spring boot版本区间


官方:Spring AI
2.2 创建子工程

2.2.1 子工程引入spring ai
(把spring-ai-bom引入父工程也行,这样所有的子工程就都相当于引入了这个依赖)
子工程引入依赖:
(你或许不知道"spring-ai-starter-model-openai"这个依赖是干什么的,但没关系,下面会讲解)
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- 引入OpenAI API 协议 --> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-model-openai</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-bom</artifactId> <version>2.0.1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
2.2.2 spring-ai-starter-model-openai
Spring AI 生态专门为OpenAI及兼容其API服务的大模型设计了**"spring-ai-starter-model-openai"**用于快速集成大语言模型能力到spring boot应用中。(如DeepSeek也兼容了OpenAI)

同一个文档页面往下话到底,就看到:

该依赖核心价值包括:
- 简化配置:自动封装OpenAI API的请求和响应
- 统一接口:提供ChatClient等标准化接口,支持无缝切换不同模型提供商
- Spring 生态集成:与Spring Boot的自动配置、依赖注入等特性深度整合
核心价值解释:
1.简化配置:兼容了OpenAI API格式的模型都可以引入"spring-ai-starter-model-openai"后,通过配置文件(如application.yml)或代码 组装成一个OpenAI API格式的API请求。
以发送DeepSeek API请求为例。DeepSeek兼容了OpenAI API格式,因此可以在application.yml文件中配置如下:

上图中,我申请的DeepSeek的api-key配置到了环境变量中,你也可以把api-key直接粘贴,例api-key: sk-123...321
3. 构建API请求的原理
上图配置操作非常简单,但是为什么如这样简单的配置就构建了一个API请求?------你猜的没错!引入的**"spring-ai-starter-model-openai"**依赖使用了OpenAI API请求模板:
nitice:以DeepSeek官方示例为例。DeepSeek官方提供了一些配置选项,选择后,API请求就会在带有哪些配置。

2.统一接口 和 3.Spring 生态集成 这两价值现在不好直接体现,请直接看实战。
4. DeepSeek AI聊天实战(ChatModel)

- 配置聊天大模型后,在需要使用时,直接注入ChatModel(OpenAiChatModel实现了ChatModel。也可以一个构造ChatClient,后面讲)
- call(String)方法,把用户输入的信息(用户提示词)传给聊天大模型,大模型通过自己已有的知识,回答你。是对话式AI应用最核心的方法,通过call调用AI。
java
package com.jusheshen.ai.controller;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/deepseek")
@RestController
public class DeepSeekController {
@Autowired
private OpenAiChatModel dsChatModel; //注入DeepSeek的deepseek-v4-flash模型,因为yml配置的base-url是deepseek
@RequestMapping("/chat")
public String chat(String prompt){ //用户输入提示词
String call = dsChatModel.call(prompt); //用户提示词传给大模型,模型处理后返回处理结果
return call;
}
}
1.notice:Spring AI给我们提供了许多可配置的选项:

2.notice :在Spring AI 1.0.0-M6及更早,starter 还叫"spring-ai-openai-spring-boot-starter",Spring AI 1.0.0-M7及之后版本改名叫"spring-ai-starter-model-openai"
随着Spring AI版本的改变,有一些工件ID也发生了变化,如果哪天依赖用着用着出错了,就来Upgrade Notes :: Spring AI Reference 看看是否发生改变。
3.notice: Spring AI已经为主流的模型供应商提供了单独的适配器,如DeepSeek可引入"spring-ai-starter-model-deepseek"。但更提倡引用"spring-ai-starter-model-openai",因为许多供应商兼容OpenAI API格式,在切换大模型时可以省掉部分替换依赖的时间。
如上述,如果想把DeepSeek的模型换成ChatGPT的话直接改base-url、model和api-key就行。(base-url不写都可以,ChatGPT本身就是OpenAI的模型,有默认的base-url)
5. ChatClient接口
- ChatModel和ChatClient 是Spring AI框架构建对话式AI应用的两大核心接口,上面使用了ChatModel完成与AI模型的交互。接下来介绍ChatModel和ChatClient的区别。
- ChatClient 对ChatModel进行了封装,ChatModel更接近底层(大模型),ChatClient提供给用户开箱即用的服务。ChatClient实现了Fluent API可链式调用,它还支持同步和异步调用大模型。
官方示例:Chat Client API :: Spring AI Reference
java
@RestController
class MyController {
private final ChatClient chatClient;
//ChatClient.Builder就是ChatModel,替换成ChatModel 更直观
public MyController(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder.build();
}
@GetMapping("/ai")
String generation(String userInput) {
return this.chatClient.prompt()//链式调用
.user(userInput)
.call()
.content();
}
}
下面我接着以DeepSeek模型为例,你也可以配置其他厂商的模型。
6. DeepSeek AI聊天实战(ChatClient)
6.1 实战1(系统提示词)


6.2 实战2(结构化输出)
上述AI返回信息没有固定格式,有时候信息冗余在一块。ChatClient允许自定义AI返回类型,以下面为例:
构建一个输入菜名,返回所需配料的AI。并且自定义菜谱类。


其实代码层面,我根本没和AI说食谱类的dish属性是什么意思,ingredients是什么意思,但AI就是知道把菜名赋给dish,配料赋给ingredients。可看出AI很聪明。
6.3 实战3(流式输出)
平时在其他平台与AI对话时,你可能注意注意到 AI回复的信息都是一个字一个字的往外蹦的。我上面与AI所有的交互都是等AI大模型处理、返回完,再全部信息返回给后端,接着再return给前端,这就导致在处理复杂问题时,用户在前端要面对一个白板很长时间,这体验感真是糟糕透了,所以下面实现流式输出。
notice:一定要设置编码,否则输出的就是中文乱码!
java
@RequestMapping(value = "/stream",produces = "text/html;charset=utf-8")
public Flux<String> stream(String message){
return chatClient.prompt()
.user(message)
//调用AI 流式输出
.stream()
//返回数据
.content();
}
7. Advisors介绍
Spring AI中的Advisors是基于AOP思想实现的,Advisors类似于Spring中的拦截器。下图是Advisor的执行时机,这种链式处理机制确保了每个Advisor都会被执行。Advisor的核心功能 在于对请求进行拦截过滤 和增强, 帮助我们在API调用前后解决各种问题。

以SimpleLoggleAdvisor为例。
7.1 SimpleLoggleAdvisor
SimpleLoggleAdvisor是Spring AI内置的Advisor之一,主要用来打印日志。手动添加到Advisor链中,即可自动打印所有经过大模型的聊天请求和响应。

可以为每⼀次的对话设置advisor. 如果default也设置了同⼀类型的Advisor, 那么对话级别的优先级
⾼于default.
SimpleLoggleAdvisor效果展示:

对于SimpleLoggleAdvisor打印的日志级别,可以自定义,而且自定义的模板与spring boot一样。
logging: level: org.springframework.ai.chat.client.advisor: debug