Spring AI 進階之路01:三步將 AI 整合進 Spring Boot

引子

LLM 的浪潮以不可阻擋之勢席卷全球,從改變用戶交互到重塑商業模式,我們每一位開發者都身處這場技術變革的中心。作為龐大的 Java 生態中的一員,你是否也曾思考:當 Python 似乎成為 AI 的“官方語言”時,我們這些深耕 Spring 全家桶的開發者,該如何快速擁抱這個新時代?如今,Spring 團隊親自出手,為數百萬 Java 開發者帶來了官方答案——Spring AI。它將 AI 開發的復雜性進行封裝,讓集成 AI 能力變得像添加一個普通的 Starter 一樣簡單。

本文是 《Spring AI 進階之路》 系列的第一篇,我們將從最基礎的整合開始。你將看到,在 Spring Boot 的幫助下,集成一個強大的 AI 模型,真的只需三步!

話不多說,讓我們直接開始動手實踐。

前置準備

在開始三步集成前,先確保你已準備好以下基礎環境:

  1. JDK 17+:Spring Boot 3 和 Spring AI 基于較新的 Java 版本,確保你的 JDK 版本不低于 17。
  2. Maven 或 Gradle:本文以 Maven 為例,它是我們管理項目依賴的得力助手。
  3. 一個順手的 IDE:選擇你最熟悉的 IDE 即可,本文以 IntelliJ IDEA 為例。
  4. 一個 LLM廠商的 API Key:本文以 DeepSeek 為例,價格便宜且無需科學上網,使用起來很方便。

第一步:添加依賴

讓我們從創建項目開始。如果你使用 Spring Initializr 會更簡單,但為了讓大家理解每一步的細節,我們選擇從零開始創建一個 Maven 項目。

首先,創建一個新的Maven空項目:
在這里插入圖片描述

項目創建完成后,我們需要配置 pom.xml。整個依賴配置分為三個部分:

1.設置 Spring Boot 父項目

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.5.0</version>
</parent>

2.管理 Spring AI 的版本

通過 BOM 統一管理 Spring AI相關依賴的版本,避免版本沖突:

<dependencyManagement><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>1.0.0</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement>

3.添加具體依賴

<dependencies><!-- Spring Boot Web Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring AI OpenAI Starter --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-model-openai</artifactId></dependency>
</dependencies>

你可能注意到,雖然我們前面提到本次使用的是 DeepSeek 的 API,但引入的卻是 spring-ai-starter-model-openai。這是因為 DeepSeek 采用了與 OpenAI 完全兼容的 API 規范,我們可以直接復用 OpenAI 的客戶端實現。這種設計讓切換不同的 AI 服務商變得非常簡單——只需要更換 API Key 和端點地址即可。

第二步:配置憑證

有了依賴,接下來需要告訴 Spring AI 如何連接到 AI 服務。在 src/main/resources 目錄下創建 application.yml 文件(如果不存在的話),添加以下配置:

spring:ai:openai:api-key: {這里換成你自己的}base-url: https://api.deepseek.comchat:options:model: deepseek-chat

?? 提醒:直接將 API Key 寫在配置文件中僅適合本地開發和快速測試,但絕對不要在生產環境中這樣做!在生產環境中,推薦使用環境變量來管理你的密鑰。

第三步:編寫代碼調用

萬事俱備,讓我們開始編寫代碼來調用 AI 模型。

1.注入AI客戶端

接下來,創建一個 REST 控制器來處理 AI 對話請求。Spring AI 的魅力在于,它將復雜的 AI 交互抽象成了簡單的 Spring Bean:

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/chat")
public class ChatController {private ChatClient chatClient;public ChatController(ChatClient.Builder chatClientBuilder) {this.chatClient = chatClientBuilder.build();}@GetMapping("/test")public String completion(@RequestParam String message) {return chatClient.prompt().user(message).call().content();}  }

2.啟動測試

啟動應用,Spring Boot 的控制臺會顯示啟動信息。待應用成功啟動后,我們可以通過Apifox,向這個測試接口發送請求:
在這里插入圖片描述

3.配置跨域

最終我們一定需要從前端應用調用這個接口,所以別忘了配置 CORS:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class CorsConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOrigins("/chat/*").allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS").allowedHeaders("*").allowCredentials(true).maxAge(3600);}
}

小結

至此,我們完成了 Spring AI 的基礎集成。不過,如果你仔細觀察測試結果,會發現當前的實現存在一個明顯的體驗問題:我們必須等待 AI 完全生成答案后才能看到結果。相比之下,那種逐字輸出的效果就友好得多。用戶能實時看到 AI 的"思考過程",體驗更加流暢自然。

那么,如何在 Spring AI 中實現這種流式響應呢?這正是下一篇文章要探討的內容。我們將介紹如何使用 SSE(Server-Sent Events)技術,讓你的 AI 應用也能實現實時的打字機效果。

如果你對本文有任何疑問或建議,歡迎在評論區交流。下篇見!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/93619.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/93619.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/93619.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

pycharm2025導入anaconda創建的各個AI環境

目錄1.pycharm下載及安裝2.導入anaconda的環境到pycharm項目中1.pycharm下載及安裝 建議從官網下載&#xff0c;不要亂下載。 https://www.jetbrains.com.cn/en-us/pycharm/ 右上角可以切換中英文&#xff0c;在此切換為中文。 點擊下載&#xff0c;如下頁面: 點擊中間下載w…

獲取IPv6地址的三種方式

DHCPv6無狀態自動分配IP地址Server 配置&#xff1a;<Huawei>system-view[Huawei]ipv6[Huawei]dhcp enable[Huawei]dhcpv6 pool pool1[Huawei-dhcpv6-pool-pool1]dns-server 2002::2[Huawei-dhcpv6-pool-pool1]dns-domain-name example.com[Huawei-dhcpv6-pool-pool1]qui…

[Oracle數據庫] Oracle 復雜查詢

對于剛接觸 Oracle 數據庫的初學者來說&#xff0c;簡單查詢&#xff08;如SELECT * FROM 表名&#xff09;可能不難掌握&#xff0c;但面對復雜業務場景時&#xff0c;就需要更強大的查詢能力。本文將圍繞 Oracle 復雜查詢的核心知識點展開&#xff0c;包括條件邏輯、分組函數…

Redis-plus-plus API使用指南:通用操作與數據類型接口介紹

&#x1f351;個人主頁&#xff1a;Jupiter.&#x1f680; 所屬專欄&#xff1a;Redis 歡迎大家點贊收藏評論&#x1f60a;目錄通用 API連接 Redis1. get/set2. exists 方法3. del 方法4. keys 方法5. expire 方法6. ttl 方法7. type 方法8. flushall 方法String 類型 API1. ge…

基于遺傳編程的自動程序生成

這里寫目錄標題核心概念與工作原理1. 個體表示&#xff1a;樹結構2. 初始化種群3. 適應度評估4. 選擇5. 遺傳操作&#xff08;繁殖&#xff09;6. 新一代種群形成7. 終止條件基于遺傳編程的符號回歸示例問題示例GP實現符號回歸&#xff08;Deap&#xff09;GP實現符號回歸&…

flowable匯總查詢方式

背景&#xff1a;小程序開發申請流程。使用flowable流程框架。用戶需要在后臺統攬用戶申請的匯總表。 設計思路&#xff1a;通過查詢流程實例分頁查詢獲取數據&#xff0c; 其中可以通過查詢條件進行查詢&#xff0c;查詢條件是流程申請時添加到流程變量當中的&#xff0c;方便…

力扣438:找到字符串中所有的字母異位詞

力扣438:找到字符串中所有的字母異位詞題目思路代碼題目 給定兩個字符串 s 和 p&#xff0c;找到 s 中所有 p 的 異位詞 的子串&#xff0c;返回這些子串的起始索引。不考慮答案輸出的順序。 思路 我們先不看異位詞這個條件&#xff0c;如何在字符串s中找到字符串p。我們可以…

ruoyi-vue(十一)——代碼生成

大部分項目里其實有很多代碼都是重復的&#xff0c;幾乎每個基礎模塊的代碼都有增刪改查的功能&#xff0c;而這些功能都是大同小異&#xff0c; 如果這些功能都要自己去寫&#xff0c;將會大大浪費我們的精力降低效率。所以這種重復性的代碼可以使用代碼生成。一 代碼生成使用…

neo4j導入導出方法

在 Neo4j 中&#xff0c;如果需要將數據從 一個環境導出&#xff0c;再 導入到另一個環境&#xff08;如從開發環境遷移到生產環境&#xff09;&#xff0c;可以通過以下方法實現&#xff1a;方法 1&#xff1a;使用 neo4j-admin 導出和導入&#xff08;完整數據庫遷移&#xf…

Diamond基礎2:開發流程之LedDemo

文章目錄1.關聯VS Code2.Diamond工程目錄3.Led Demo開發流程4.燒寫bit文件5.傳送門1.關聯VS Code 和Vivado一樣&#xff0c;Diamond也可以使用第三方的編輯器&#xff0c;VS Code編輯器因為可以安裝各種插件&#xff0c;并且對verilog開發的支持也算完善&#xff0c;所以很受歡…

Golang 后臺技術面試套題 1

文章目錄1.網絡1.1 瀏覽器從輸入網址到展示頁面&#xff0c;描述下整個過程&#xff1f;1.2 HTTP 502&#xff0c;503 和 504 是什么含義&#xff1f;區別以及如何排查&#xff1f;1.3 HTTPS 通信過程為什么要約定加密密鑰 code&#xff0c;用非對稱加密不行嗎&#xff1f;1.4 …

【科研繪圖系列】R語言繪制蝶形條形圖蝶形柱狀堆積圖

文章目錄 介紹 加載R包 數據下載 導入數據 數據預處理 畫圖 系統信息 參考 介紹 【科研繪圖系列】R語言繪制蝶形條形圖&蝶形柱狀堆積圖 加載R包 library(tidyverse) library(ggsignif) library(RColorBrewer) library(dplyr) library(reshape2) library(grid

Jeecg后端經驗匯總

Jeecg是一個不錯的低代碼平臺&#xff0c;極大的降低了很多開發人員接私活的難度&#xff0c;也極大的降低了開發全套功能的難度。但是一碼歸一碼&#xff0c;開發人員的水平很一般&#xff0c;如下&#xff1a;&#xff08;1&#xff09;普通用戶可以修改管理員密碼&#xff0…

ethernet_input到應用層處理簡單分析

1、驅動層&#xff1a;從硬件讀取數據并構造pbuf中斷觸發后&#xff0c;驅動層的接收任務&#xff08;或輪詢函數&#xff09;會從網卡硬件讀取數據&#xff0c;并將其封裝為 LWIP 可識別的pbuf結構體&#xff08;LWIP 的數據緩沖區&#xff09;。關鍵函數&#xff1a;驅動自定…

C#WPF實戰出真汁05--左側導航

1、左側導航設計要點清晰的信息架構 確保導航結構層次分明&#xff0c;主分類與子分類邏輯清晰&#xff0c;避免過度嵌套。使用分組、縮進或分隔線區分不同層級&#xff0c;保持視覺可讀性。直觀的圖標與標簽 為每個導航項搭配簡潔的圖標&#xff0c;強化視覺識別。標簽文字需簡…

大模擬 Major

題目來源&#xff1a;2025 Wuhan University of Technology Programming Contest 比賽鏈接&#xff1a;Dashboard - 2025 Wuhan University of Technology Programming Contest - Codeforces 題目大意&#xff1a; 模擬 16 支隊伍的瑞士輪比賽結果&#xff0c;規則太多&…

【手撕JAVA多線程】1.從設計初衷去看JAVA的線程操作

目錄 前言 概述 主動阻塞/喚醒 代碼示例 實現 為什么必須在同步塊中使用 計時等待是如何實現的 被動阻塞/喚醒 為什么要有被動阻塞/喚醒 實現&#xff08;鎖升級&#xff09; 前言 JAVA多線程相關的內容很多很雜&#xff0c;但工作中用到的頻率不高&#xff0c;用到…

UE5多人MOBA+GAS 46、制作龍卷風技能

文章目錄創建龍卷風GA創建蒙太奇創捷一系列GE添加數據表添加到角色中創建龍卷風GA GA_Tornado 添加標簽 // 龍卷風冷卻CRUNCH_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Ability_Tornado_Cooldown)// 通用技能傷害CRUNCH_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(Ability_Generic_Dama…

如何在ubuntu下安裝libgpiod庫

以下是關于如何在ubuntu下安裝libgpiod庫的兩種安裝方式以及遇到ubuntu存在多個工具鏈導致編譯失敗的解決方法。如果想要自由選擇使用不同版本的libgpiod&#xff0c;可以選擇手動編譯安裝方式&#xff0c;系統安裝默認1.6.3版本(ubuntu22.04)。手動編譯安裝1、在github上下載要…

qt vs2019編譯QXlsx

1、安裝ActivePerl2、打開pro文件&#xff0c;直接編譯即可第一個簡單實例&#xff1a;#include "xlsxcellrange.h" #include "xlsxchart.h" #include "xlsxchartsheet.h" #include "xlsxdocument.h" #include "xlsxrichstring.h…