2026年6月,Spring生态迎来了两个里程碑级的发布:6月10日Spring Boot 4.1正式发布;6月12日Spring AI 2.0.0 GA同步上线。Spring AI 2.0被设计为与Spring Boot 4.0/4.1和Spring Framework 7.0配合使用——Spring官方正在把“AI集成”变成Spring生态的一等公民。

本文将从零开始,带你构建一个完整的企业级AI应用,覆盖结构化输出、工具调用(Tool Calling)、MCP服务器三大核心能力,并结合Spring Boot 4.1的生产级特性,让代码真正可落地。

技术栈:Java 21 + Spring Boot 4.1.0 + Spring AI 2.0.0 GA


一、项目初始化:5分钟搭好骨架

1.1 创建Spring Boot项目

使用Spring Initializr或IDE创建项目,核心依赖如下:

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

<properties>
    <java.version>21</java.version>
    <spring-ai.version>2.0.0</spring-ai.version>
</properties>

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

<dependencies>
    <!-- Spring AI 核心 -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-starter</artifactId>
    </dependency>
    <!-- OpenAI 适配(也兼容其他OpenAI API的模型) -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
    </dependency>
    <!-- Spring Boot Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

Spring AI 2.0将支持的模型提供方收敛为一组明确定义的核心集:OpenAI(从3种变体统一为1种SDK,同时兼容OpenAI API的其他模型)、Anthropic(从2种变体统一为1种SDK)、Amazon Bedrock、Google GenAI等。这意味着你使用同一套ChatClient API,就可以切换不同的模型提供商。

1.2 配置模型连接

application.yml 中配置API密钥(以OpenAI为例):

spring:
  ai:
    openai:
      api-key: ${OPENAI_API_KEY}
      base-url: ${OPENAI_BASE_URL:https://api.openai.com}
      chat:
        options:
          model: gpt-4o
          temperature: 0.7

Spring Boot的自动配置会为你创建好 ChatModelChatClient.Builder Bean。


二、核心能力一:结构化输出——让AI返回“类型安全”的数据

大语言模型是“文本进、文本出”的系统。当下游代码需要根据字段做路由、持久化或分支判断时,文本必须变成类型化的记录。Spring AI通过 ChatClient.entity() 方法解决了这个问题。

2.1 定义返回类型
public record CustomerSupportTicket(
    String ticketId,
    String category,      // "技术问题" | "账单咨询" | "产品建议"
    String priority,      // "高" | "中" | "低"
    String summary,
    String suggestedAction,
    List<String> relatedArticles
) {}
2.2 基础用法:让AI填充对象
@Service
public class TicketAnalysisService {
    private final ChatClient chatClient;

    public TicketAnalysisService(ChatClient.Builder builder) {
        this.chatClient = builder.build();
    }

    public CustomerSupportTicket analyzeTicket(String userMessage) {
        return chatClient.prompt()
            .user("""
                请分析以下客户反馈,按工单分类、优先级、摘要、建议操作和相关文章生成结构化输出:
                
                客户反馈:%s
                """.formatted(userMessage))
            .call()
            .entity(CustomerSupportTicket.class);
    }
}

entity(CustomerSupportTicket.class) 背后做了三件事:将 CustomerSupportTicket 记录生成JSON Schema,将Schema追加到提示词的系统上下文中,然后将模型的JSON答案反序列化为你的记录。

2.3 可靠性升级:自纠错验证

基础用法有一个问题:模型是被“请求”生成符合Schema的JSON,而不是被“强制”。有时它会多返回一个字段、遗漏必填字段,或者把JSON包在散文里。

Spring AI 2.0 的 validateSchema() 解决了这个问题

public CustomerSupportTicket analyzeTicketWithRetry(String userMessage) {
    return chatClient.prompt()
        .user("""
            请分析以下客户反馈,按工单分类、优先级、摘要、建议操作和相关文章生成结构化输出:
            
            客户反馈:%s
            """.formatted(userMessage))
        .call()
        .entity(CustomerSupportTicket.class, spec -> spec.validateSchema());
}

开启 validateSchema() 后,Spring AI会启动一个自纠错重试循环

  1. 模型返回响应
  2. Spring AI 验证响应是否符合 CustomerSupportTicket 的Schema
  3. 验证通过 → 返回类型化记录
  4. 验证失败 → 将具体的校验错误(如“缺少必填字段category”、“期望数组却得到字符串”)追加到用户提示中,重新发起调用——默认最多重试3次

第二次尝试不是盲目重试;模型看到了上一次的错误原因,能够有针对性地修正输出。


三、核心能力二:工具调用——让AI“动手做事”

工具调用(Tool Calling)是代理式AI系统的核心构建块。一个只能生成文本的模型是聊天机器人;一个能够发现信息、采取行动并循环直到达成目标的模型才是Agent

Spring AI 2.0 将工具调用从底层重构为 ChatClient 顾问链中的一等公民。在1.x中,每个ChatModel实现都包含自己的私有工具执行循环——功能可用,但无法被钩入、观测或组合。2.0将其提升为可组合的顾问组件。

3.1 用 @Tool 定义工具

Spring AI 2.0 推荐使用声明式的 @Tool 注解:

@Component
public class OrderTools {
    
    private final OrderService orderService;

    public OrderTools(OrderService orderService) {
        this.orderService = orderService;
    }

    @Tool(description = "根据订单号查询订单状态,返回订单的当前状态、金额和预计送达时间")
    public OrderStatus getOrderStatus(
        @ToolParam(description = "订单号,格式为 ORD-xxxxxx") String orderId
    ) {
        return orderService.findStatus(orderId);
    }

    @Tool(description = "取消指定订单,仅当订单状态为'待发货'时可以取消")
    public CancelResult cancelOrder(
        @ToolParam(description = "要取消的订单号") String orderId,
        @ToolParam(description = "取消原因") String reason
    ) {
        return orderService.cancel(orderId, reason);
    }
}

Spring AI会自动生成输入参数的JSON Schema。@ToolParam 为每个参数添加描述和可选/必填提示。

3.2 将工具注册到 ChatClient

工具通过 .tools() 显式传递给 ChatClient

@Service
public class OrderAssistantService {
    private final ChatClient chatClient;
    private final OrderTools orderTools;

    public OrderAssistantService(ChatClient.Builder builder, OrderTools orderTools) {
        this.chatClient = builder.build();
        this.orderTools = orderTools;
    }

    public String handleUserQuery(String userMessage) {
        return chatClient.prompt()
            .user(userMessage)
            .tools(orderTools)
            .call()
            .content();
    }
}
3.3 工具调用循环的工作原理

当用户问“我的订单ORD-123456现在什么状态?”时,底层 ToolCallingAdvisor 驱动的循环如下:

  1. 第一轮:模型分析用户问题,发现需要调用 getOrderStatus 工具,返回工具调用请求
  2. 执行ToolCallingManager 找到并执行 getOrderStatus 方法
  3. 第二轮:工具执行结果(订单状态)被追加到对话历史中,再次发给模型
  4. 最终响应:模型基于工具返回的数据生成自然语言回复:“您的订单ORD-123456当前状态为‘已发货’,预计送达时间为...”

整个过程对开发者完全透明——你只需要定义工具并注册,ToolCallingAdvisor 会处理所有的循环逻辑。


四、核心能力三:MCP服务器——让外部AI调用你的业务能力

Model Context Protocol(MCP)是一个开放标准,定义了AI模型如何与外部工具、服务和数据源通信。它用单一的、定义良好的JSON-RPC 2.0协议取代了临时性的集成方案。

一个有用的心智模型:把MCP想象成AI集成的USB-C——一个标准端口,连接多种设备

4.1 添加MCP依赖
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
</dependency>
4.2 配置MCP传输层
# application.yml
spring:
  ai:
    mcp:
      server:
        name: enterprise-mcp-server
        version: 1.0.0
        type: SYNC
        protocol: STREAMABLE

server:
  port: 8080

protocol: STREAMABLE 选择Streamable HTTP传输——一个单一的 POST /mcp 端点通过JSON-RPC通信。Spring AI会自动注册这个端点,无需编写任何控制器代码

4.3 用 @McpTool 暴露工具
@Component
public class PolicyNumberTools {
    
    @McpTool(description = "为指定险种生成新的保单号")
    public String createPolicyNumber(
        @McpToolParam(description = "险种ID,如'LI'(寿险)、'HE'(健康险)") String lobId,
        @McpToolParam(description = "投保人姓名") String applicantName
    ) {
        String timestamp = LocalDateTime.now()
            .format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        return lobId + "-" + timestamp + "-" + applicantName.substring(0, 2).toUpperCase();
    }

    @McpTool(description = "验证保单号是否有效")
    public boolean validatePolicyNumber(
        @McpToolParam(description = "待验证的保单号") String policyNumber
    ) {
        return policyNumber != null && policyNumber.matches("^[A-Z]{2}-\\d{14}-[A-Z]{2}$");
    }
}

@McpTool@Tool 类似,Spring AI会自动生成参数的JSON Schema。

4.4 暴露只读资源

除了工具(可调用函数),MCP服务器还可以暴露资源——只读的、URI可寻址的内容:

@Component
public class PolicyResource {
    
    @McpResource(uri = "policies://current/{userId}", 
                 description = "获取指定用户当前有效的所有保单")
    public List<PolicySummary> getCurrentPolicies(
        @McpResourceParam(description = "用户ID") String userId
    ) {
        return policyService.findActivePoliciesByUser(userId);
    }
}
4.5 测试MCP服务器

启动应用后,可以用 curl 测试:

curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "tools/list",
    "id": 1
  }'

任何MCP兼容的客户端(Claude Desktop、VS Code、Cursor或你自己的Spring应用)都可以连接这个服务器。


五、生产就绪:Spring Boot 4.1 的企业级增强

Spring AI 2.0解决了“如何构建AI应用”的架构问题,而Spring Boot 4.1解决了“AI应用跑在哪里”的基础设施问题。

5.1 gRPC原生支持

Spring Boot 4.1 开始提供gRPC的自动配置。对于AI应用中内部服务间的高频调用,gRPC比REST更高效:

// 定义gRPC服务(通过proto文件编译生成)
@GrpcService
public class AIGrpcService extends AIServiceGrpc.AIServiceImplBase {
    private final ChatClient chatClient;
    
    @Override
    public void chat(ChatRequest request, 
                     StreamObserver<ChatResponse> responseObserver) {
        String result = chatClient.prompt()
            .user(request.getUserMessage())
            .call()
            .content();
        responseObserver.onNext(ChatResponse.newBuilder()
            .setContent(result).build());
        responseObserver.onCompleted();
    }
}
5.2 SSRF防护

Spring Boot 4.1新增的 InetAddressFilter 可以拦截HTTP客户端向特定地址范围的出站请求。当AI Agent根据用户输入或模型输出动态访问外部URL时,这是实打实的安全防线

spring:
  web:
    client:
      ssrf:
        enabled: true
        allowed-ip-ranges:
          - "10.0.0.0/8"
          - "172.16.0.0/12"
          - "192.168.0.0/16"
5.3 OpenTelemetry观测增强

Spring Boot 4.1 增强了 @Async 方法的上下文传播、Kafka/RabbitMQ的观测自动应用。在AI应用里,一次请求可能经过HTTP接入→模型调用→工具调用→数据库→消息队列→异步任务,链路观测不是“锦上添花”,而是“生存刚需”。


六、国产化部署:金蝶天燕AAS的AI时代站位

当上述Spring Boot 4.1 + Spring AI 2.0应用需要部署在国产化环境中时,金蝶Apusic应用服务器(AAS)V10 提供了一个经过国际权威验证的可靠底座。

金蝶AAS V10已正式通过Jakarta EE 11国际认证,在保持企业级稳定性的同时全面向云原生和现代开发范式靠拢。对于采用Spring Boot 4.1构建AI应用的政企客户而言,AAS V10具备以下核心能力:

  • 微内核架构:支持按需加载,降低资源占用
  • 国密算法支持:满足等保和密评合规要求
  • 国产软硬件生态适配:完整适配鲲鹏、飞腾、海光等国产芯片及统信、麒麟等国产操作系统
  • 企业级集群高可用:支持会话复制、集群部署和故障自动转移

随着Spring生态全面拥抱AI,国产中间件在“AI应用服务器”这一新赛道上的持续跟进,为政企用户的AI转型提供了自主可控的底层选择。


七、总结

本文从零开始构建了一个完整的企业级AI应用,涵盖了Spring AI 2.0的三大核心能力:

能力 核心API 解决什么问题
结构化输出 ChatClient.entity().validateSchema() 让AI返回类型安全的数据,支持自纠错
工具调用 @Tool + ChatClient.tools() 让AI调用业务方法,执行实际操作
MCP服务器 @McpTool + @McpResource 让外部AI客户端调用你的业务能力

Spring AI 2.0 的使命是“连接企业数据和API与AI模型”。当这套连接建立在Spring Boot 4.1提供的生产级基础设施(gRPC、SSRF防护、OpenTelemetry)之上,Java开发者终于可以用自己最熟悉的方式,大规模构建可靠、可观测、可维护的AI应用——无需切换技术栈,无需Python背景

所有的示例代码都可以直接复制到你的项目中运行。下一步,不妨试着将 OrderTools 替换为你自己的业务工具,让AI真正成为你系统的“智能伙伴”。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐