Spring AI 2.0 GA 实战:构建生产级 AI Agent 系统——Advisor 链、MCP 2.0 与工具发现机制全解析

Spring AI 2.0 GA 实战:构建生产级 AI Agent 系统------Advisor 链、MCP 2.0 与工具发现机制全解析

2026 年 6 月 12 日,Spring AI 2.0.0 正式 GA。这不是一次简单的版本号升级------它重新定义了 Java 生态中 AI Agent 的构建方式。本文将深入解析 Spring AI 2.0 的核心架构变化,并通过完整代码示例带你实战上手。

作者:超人不会飞


一、为什么 Spring AI 2.0 值得关注

在 Spring AI 1.x 时代,开发者面临几个核心痛点:

  1. 工具调用循环被锁死在每个 ChatModel 内部------你想拦截、包装或替换工具执行策略?做不到。
  2. Options 和配置属性耦合严重 ------.options 前缀让人困惑,默认值散落在各处。
  3. MCP 集成停留在早期规范------SSE 传输已显过时,缺乏企业级安全与可观测性。
  4. Null 安全缺失------运行时 NPE 频发,Kotlin 开发者体验尤差。

Spring AI 2.0 用一次彻底的架构重构回答了这些问题。基于 Spring Boot 4.0 / Spring Framework 7.0 基线,引入 Jackson 3JSpecify Null 安全注解不可变 Options Builder,并将工具调用循环提升为 Advisor 链中的一等公民。


二、核心架构变化一览

2.1 基础设施升级

维度 Spring AI 1.x Spring AI 2.0
Spring Boot 基线 3.x 4.0 / 4.1
JSON 序列化 Jackson 2 Jackson 3
Null 安全 JSpecify 全量注解
Options 模型 构造函数 + 可变 Builder + 不可变
配置属性 .options 前缀 扁平化,无前缀
模型提供商 多变体(Azure/HTTP/SDK 并存) 统一 SDK 优先

2.2 聚焦的模型提供商

Spring AI 2.0 精简了内置支持,聚焦于:

  • OpenAI(SDK 实现,兼容所有 OpenAI API 协议的服务)
  • Anthropic(SDK 实现,兼容 Minimax 等)
  • Amazon Bedrock
  • Google GenAI(统一为 GenAI SDK)
  • Mistral AI
  • DeepSeek
  • Ollama

OCI Generative AI 和 Azure Cosmos DB 等由厂商直接维护,这种分工模式让核心代码库更聚焦。


三、Advisor 链:AI Agent 的神经中枢

这是 Spring AI 2.0 最重要的架构变化。在 1.x 中,每个 ChatModel 内部都有一个私有的工具调用循环,你无法介入。2.0 将这个循环提升到了 Advisor 链 中。

3.1 什么是 Advisor 链

ChatClient 的每次请求都会经过一个有序的 Advisor 链。Advisor 可以:

  • 拦截请求和响应(日志、审计、限流)

  • 循环------让下游链重新进入(工具调用循环、结构化输出重试循环、评估循环)

  • 组合 ------多个 Advisor 按顺序协作

    User Request


    ┌─────────────────────────────┐
    │ Advisor Chain │
    │ ┌───────────────────────┐ │
    │ │ LoggingAdvisor │ │
    │ │ → log request │ │
    │ ├───────────────────────┤ │
    │ │ ToolCallingAdvisor │ │◄── Auto-registered
    │ │ → execute tools │ │
    │ │ → loop until done │ │
    │ ├───────────────────────┤ │
    │ │ StructuredOutput │ │◄── Auto-registered
    │ │ ValidationAdvisor │ │
    │ │ → validate & retry │ │
    │ ├───────────────────────┤ │
    │ │ ToolSearchAdvisor │ │◄── Optional
    │ │ → progressive │ │
    │ │ tool discovery │ │
    │ └───────────────────────┘ │
    └─────────────────────────────┘


    ChatModel (pure inference)

3.2 ToolCallingAdvisor 实战

ToolCallingAdvisor 是自动注册的,它实现了完整的工具调用往返:

java 复制代码
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Service;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class AgentApplication {
    public static void main(String[] args) {
        SpringApplication.run(AgentApplication.class, args);
    }
}

/**
 * 股票查询工具 - 使用 @Tool 注解声明
 * Spring AI 2.0 会自动将其注册到 ToolCallingAdvisor
 */
@Service
public class StockQueryService {

    @Tool(description = "查询指定股票代码的实时行情数据,包括价格、涨跌幅、成交量")
    public StockQuote getRealtimeQuote(
            @ToolParam(description = "股票代码,如 600519.SH") String stockCode) {
        // 实际项目中这里会调用行情 API
        return new StockQuote(stockCode, 1850.50, 2.35, 12500000);
    }

    @Tool(description = "查询指定股票的历史K线数据")
    public List<KlineData> getHistoryKline(
            @ToolParam(description = "股票代码") String stockCode,
            @ToolParam(description = "天数,默认30天") int days) {
        // 返回模拟K线数据
        return KlineData.generateMockData(stockCode, days);
    }
}

/**
 * 行情数据 DTO
 */
public record StockQuote(
    String code,
    double price,
    double changePercent,
    long volume
) {}

/**
 * K线数据 DTO
 */
public record KlineData(
    String date,
    double open,
    double close,
    double high,
    double low,
    long volume
) {
    public static List<KlineData> generateMockData(String code, int days) {
        // 模拟数据生成
        return java.util.stream.IntStream.range(0, days)
            .mapToObj(i -> new KlineData(
                java.time.LocalDate.now().minusDays(days - i).toString(),
                1800 + Math.random() * 100,
                1800 + Math.random() * 100,
                1850 + Math.random() * 50,
                1780 + Math.random() * 50,
                (long)(Math.random() * 20000000)
            ))
            .toList();
    }
}

配置 ChatClient 并调用:

java 复制代码
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ChatClientConfig {

    @Bean
    public ChatClient chatClient(ChatClient.Builder builder,
                                  StockQueryService stockService) {
        return builder
            .defaultSystem("你是一个专业的A股分析助手,请根据用户的问题调用相应工具获取数据后给出分析。")
            .defaultTools(stockService)  // 注册工具,ToolCallingAdvisor 自动接管
            .build();
    }
}

/**
 * Agent 控制器 - 处理用户查询
 */
@RestController
@RequestMapping("/api/agent")
public class AgentController {

    private final ChatClient chatClient;

    public AgentController(ChatClient chatClient) {
        this.chatClient = chatClient;
    }

    @PostMapping("/chat")
    public ResponseEntity<String> chat(@RequestBody ChatRequest request) {
        String response = chatClient.prompt()
            .user(request.getMessage())
            .call()
            .content();
        return ResponseEntity.ok(response);
    }
}

public record ChatRequest(String message) {}

关键理解 :你不需要手动管理工具调用循环。ToolCallingAdvisor 会自动:

  1. 将用户消息发送给模型
  2. 如果模型返回工具调用请求,执行对应工具
  3. 将工具结果回传给模型
  4. 重复直到模型给出最终文本回复

如果你需要更细粒度的控制(比如限制循环次数、添加人工审批环节),可以禁用自动注册并手动驱动。


四、ToolSearch:让 Agent 管理数百个工具

当你的 Agent 系统扩展到几十甚至上百个工具时,每次请求都注册所有工具会严重消耗 Token 预算。ToolSearchToolCallingAdvisor 实现了渐进式工具发现

复制代码
┌────────────────────────────────────────────┐
│         ToolSearch Flow                   │
│                                            │
│  1. Index all tools (once per session)     │
│     ┌──────┐  ┌──────┐  ┌──────┐          │
│     │Tool 1│  │Tool 2│  │Tool N│  ...     │
│     └──┬───┘  └──┬───┘  └──┬───┘          │
│        └─────────┴─────────┘               │
│              Tool Index                    │
│                                            │
│  2. Model requests → search relevant tools │
│     "I need stock data" → [getQuote,       │
│                            getKline,       │
│                            getNews]        │
│                                            │
│  3. Only matched tools sent to model       │
│     → Saves token budget                   │
│     → Reduces confusion                    │
└────────────────────────────────────────────┘
java 复制代码
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.tool.resolution.ToolSearchToolCallingAdvisor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;

@Configuration
public class ScalableAgentConfig {

    /**
     * 配置支持大量工具的 ChatClient
     * ToolSearchToolCallingAdvisor 按需暴露工具,而非全量注册
     */
    @Bean
    public ChatClient scalableChatClient(
            ChatClient.Builder builder,
            List<Object> allToolBeans) {

        return builder
            .defaultSystem("你是一个全能金融分析助手,可以根据需要查找并使用相关工具。")
            // ToolSearchToolCallingAdvisor 会索引所有工具
            // 模型每次只能看到与当前任务相关的工具子集
            .defaultAdvisors(
                new ToolSearchToolCallingAdvisor(allToolBeans)
            )
            .build();
    }
}

工作原理

  • Advisor 在会话开始时对所有工具建立索引(基于 @Tool 的 description)
  • 每次模型请求时,根据上下文搜索最相关的工具子集
  • 只有匹配的工具被发送给模型
  • 随着对话深入,工具集动态调整

五、MCP 2.0 集成:AI 应用的标准协议

5.1 什么是 MCP

Model Context Protocol (MCP) 正在成为 AI 集成的通用协议。Spring 团队同时维护着 官方 MCP Java SDK,Spring AI 2.0 直接搭载了 MCP Java SDK 2.0.0 ,遵循 2025-11-25 规范

5.2 注解驱动的 MCP Server

Spring AI 2.0 将 mcp-annotations 模块纳入核心。只需一个方法注解,就能将任何 Spring 服务暴露为 MCP Server:

java 复制代码
import org.springframework.ai.tool.mcp.annotation.McpTool;
import org.springframework.ai.tool.mcp.annotation.McpResource;
import org.springframework.ai.tool.mcp.annotation.McpPrompt;
import org.springframework.ai.tool.mcp.McpSyncRequestContext;
import org.springframework.stereotype.Service;

/**
 * MCP Server 服务 - 通过注解暴露给外部 AI Agent 使用
 * 任何 MCP 客户端(Claude Desktop、Cursor 等)都可以调用这些工具
 */
@Service
public class McpFinancialService {

    /**
     * @McpTool - 将方法暴露为 MCP 工具
     * McpSyncRequestContext 提供日志、进度报告、采样等能力
     */
    @McpTool(description = "查询A股实时行情,返回价格、涨跌幅、成交量等数据")
    public StockQuote queryStockQuote(
            String stockCode,
            McpSyncRequestContext context) {
        // 报告进度(MCP 协议支持)
        context.reportProgress(0.5, "正在获取行情数据...");

        // 调用行情服务
        StockQuote quote = fetchQuoteFromMarket(stockCode);

        // 记录审计日志
        context.log("查询股票: " + stockCode + ", 价格: " + quote.price());

        return quote;
    }

    /**
     * @McpResource - 将方法暴露为 MCP 资源(可被 Agent 读取的数据源)
     */
    @McpResource(
        uri = "market://watchlist/{userId}",
        name = "用户自选股列表",
        description = "获取指定用户的自选股列表及其最新行情"
    )
    public List<WatchlistItem> getWatchlist(String userId) {
        return watchlistRepository.findByUserId(userId);
    }

    /**
     * @McpPrompt - 将方法暴露为 MCP 提示模板
     */
    @McpPrompt(
        name = "stock-analysis",
        description = "股票深度分析提示模板"
    )
    public String stockAnalysisPrompt(String stockCode, String analysisType) {
        return String.format("""
            请对股票 %s 进行%s分析。
            分析维度包括:
            1. 基本面(PE、PB、ROE、营收增速)
            2. 技术面(均线、MACD、KDJ)
            3. 资金面(主力流向、北向资金)
            4. 行业对比(同行业PE/PB分位数)
            """, stockCode, analysisType);
    }

    private StockQuote fetchQuoteFromMarket(String code) {
        // 实际实现:调用行情 API
        return new StockQuote(code, 100.0, 1.5, 5000000);
    }

    // ... 其他依赖注入
    private final WatchlistRepository watchlistRepository;

    public McpFinancialService(WatchlistRepository watchlistRepository) {
        this.watchlistRepository = watchlistRepository;
    }
}

public record WatchlistItem(String stockCode, String stockName, double currentPrice) {}

5.3 MCP 传输层升级

Spring AI 2.0 对 MCP 传输层做了重要升级:

传输方式 状态 说明
Streamable HTTP ✅ 默认 替代 SSE,支持双向通信
Streamable HTTP (无状态) ✅ 可选 牺牲双向性换取水平扩展能力
STDIO ✅ 保留 本地进程集成
SSE ❌ 废弃 被 Streamable HTTP 取代

配置 MCP Server 传输:

yaml 复制代码
# application.yml
spring:
  ai:
    mcp:
      server:
        name: financial-tools-server
        version: 1.0.0
        transport: streamable-http  # 默认传输方式
        # 如需水平扩展,使用无状态模式:
        # transport: streamable-http-stateless

5.4 MCP 企业级特性

Spring AI 2.0 的 MCP 集成继承了完整的 Spring 生产级能力:

  • 可观测性:Micrometer Span + OpenTelemetry 兼容指标
  • 安全 :OAuth 2.0 和 API Key 认证(通过 mcp-security 项目)
  • 监控:Server 交互延迟、错误率、调用量仪表盘
java 复制代码
import io.micrometer.observation.annotation.Observed;
import org.springframework.ai.tool.mcp.annotation.McpTool;
import org.springframework.stereotype.Service;

/**
 * 带完整可观测性的 MCP 工具示例
 * Micrometer 自动记录调用耗时、成功/失败率
 */
@Service
public class ObservableMcpTools {

    @McpTool(description = "查询宏观经济数据(GDP、CPI、PMI)")
    @Observed(name = "mcp.tool.macro_data",
              contextualName = "macro-data-query")
    public MacroData queryMacroData(String indicator, String period) {
        // Micrometer 自动记录:
        // - 调用耗时
        // - 成功/失败计数
        // - 异常类型分布
        return macroDataService.query(indicator, period);
    }

    private final MacroDataService macroDataService;

    public ObservableMcpTools(MacroDataService macroDataService) {
        this.macroDataService = macroDataService;
    }
}

六、结构化输出自修正

即使开启了 Native Structured Output,模型也可能返回不合规的 JSON。StructuredOutputValidationAdvisor 会自动检测并修正:

java 复制代码
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.stereotype.Service;
import java.util.List;

/**
 * 结构化输出示例 - 自动修正不合规的 JSON
 */
@Service
public class StructuredAnalysisService {

    private final ChatClient chatClient;

    public StructuredAnalysisService(ChatClient.Builder builder) {
        this.chatClient = builder
            .defaultSystem("你是股票分析师,请严格按照指定格式输出分析结果。")
            // StructuredOutputValidationAdvisor 自动注册
            // 当模型返回不合规 JSON 时,自动重新提示模型修正
            .build();
    }

    /**
     * 获取结构化的股票分析报告
     * 返回类型定义了期望的 JSON Schema
     */
    public StockAnalysisReport analyzeStock(String stockCode) {
        return chatClient.prompt()
            .user("请分析股票 " + stockCode + " 的投资价值")
            .call()
            .entity(StockAnalysisReport.class);
    }
}

/**
 * 股票分析报告 - 结构化输出目标类
 */
public record StockAnalysisReport(
    String stockCode,
    String stockName,
    Rating rating,
    double targetPrice,
    List<String> bullReasons,
    List<String> bearReasons,
    RiskAssessment risk
) {
    public enum Rating { STRONG_BUY, BUY, HOLD, SELL, STRONG_SELL }

    public record RiskAssessment(
        int level,           // 1-5
        String description,
        List<String> factors
    ) {}
}

七、Options 重构:告别配置混乱

Spring AI 2.0 的 Options 模型做了彻底重构:

java 复制代码
import org.springframework.ai.openai.OpenAiChatOptions;

/**
 * Spring AI 2.0 Options 使用方式
 * 关键变化:
 * 1. 使用 Builder 创建,不可变
 * 2. 默认值统一在 Options 层定义
 * 3. 不再有 .options 配置前缀
 */
public class OptionsExample {

    /**
     * 方式一:在 ChatClient 级别设置默认 Options
     */
    public ChatClient createClient(ChatClient.Builder builder) {
        return builder
            .defaultOptions(
                OpenAiChatOptions.builder()
                    .model("gpt-4o")
                    .temperature(0.7)
                    .maxTokens(4096)
                    .build()  // 不可变对象
            )
            .build();
    }

    /**
     * 方式二:在请求级别覆盖 Options(作为 customizer)
     * 部分指定即可,未指定的继承默认值
     */
    public String chatWithCustomOptions(ChatClient chatClient) {
        return chatClient.prompt()
            .options(
                OpenAiChatOptions.builder()
                    .temperature(0.3)  // 只覆盖温度
                    .build()
            )
            .user("分析贵州茅台的投资价值")
            .call()
            .content();
    }
}

配置文件也变简洁了:

yaml 复制代码
# Spring AI 2.0 配置(注意:没有 .options 前缀)
spring:
  ai:
    openai:
      api-key: ${OPENAI_API_KEY}
      chat:
        model: gpt-4o
        temperature: 0.7
        max-tokens: 4096
    # MCP Server 配置
    mcp:
      server:
        name: my-agent-server
        version: 1.0.0

对比 1.x 的配置:

yaml 复制代码
# Spring AI 1.x 配置(已废弃)
spring:
  ai:
    openai:
      api-key: ${OPENAI_API_KEY}
      chat:
        options:          # ← 多余的 .options 层级
          model: gpt-4o
          temperature: 0.7

八、完整实战项目搭建

8.1 项目初始化

通过 start.spring.io 创建项目,选择:

  • Spring Boot: 4.0+
  • Dependencies: Spring AI (OpenAI), Spring Web
  • Java: 21+

8.2 Maven 依赖

xml 复制代码
<dependencies>
    <!-- Spring Boot Starter Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Spring AI OpenAI (包含核心 + MCP) -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
    </dependency>

    <!-- Spring AI MCP Annotations -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-mcp-annotations</artifactId>
    </dependency>

    <!-- 可观测性 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-tracing-bridge-otel</artifactId>
    </dependency>
</dependencies>

8.3 项目结构

复制代码
src/main/java/com/example/agent/
├── AgentApplication.java          # 主启动类
├── config/
│   ├── ChatClientConfig.java      # ChatClient 配置
│   └── McpServerConfig.java       # MCP Server 配置
├── tools/
│   ├── StockQueryService.java     # 股票查询工具
│   ├── MacroDataService.java      # 宏观数据工具
│   └── NewsSearchService.java     # 新闻搜索工具
├── mcp/
│   └── McpFinancialService.java   # MCP 对外暴露服务
├── controller/
│   └── AgentController.java       # REST API
└── model/
    ├── StockQuote.java
    ├── StockAnalysisReport.java
    └── MacroData.java

8.4 自定义 Advisor 示例

java 复制代码
import org.springframework.ai.chat.client.advisor.api.*;
import reactor.core.publisher.Flux;

/**
 * 自定义 Advisor:审计日志 + Token 用量统计
 * 演示如何在 Advisor 链中插入自定义逻辑
 */
public class AuditAdvisor implements CallAroundAdvisor, StreamAroundAdvisor {

    private final AuditRepository auditRepository;

    public AuditAdvisor(AuditRepository auditRepository) {
        this.auditRepository = auditRepository;
    }

    @Override
    public String getName() {
        return "AuditAdvisor";
    }

    @Override
    public int getOrder() {
        // 在 ToolCallingAdvisor 之前执行(默认 0)
        return -10;
    }

    @Override
    public AdvisedResponse aroundCall(AdvisedRequest request,
                                       CallAroundAdvisorChain chain) {
        // 请求前:记录输入
        long startTime = System.currentTimeMillis();
        auditRepository.logRequest(
            request.userText(),
            request.systemText(),
            request.tools().size()
        );

        // 执行下游链(包括 ToolCallingAdvisor、模型调用等)
        AdvisedResponse response = chain.nextAroundCall(request);

        // 请求后:记录输出和耗时
        long duration = System.currentTimeMillis() - startTime;
        auditRepository.logResponse(
            response.response().getResult().getOutput().getText(),
            duration,
            response.response().getMetadata().getUsage()
        );

        return response;
    }

    @Override
    public Flux<AdvisedResponse> aroundStream(AdvisedRequest request,
                                                StreamAroundAdvisorChain chain) {
        // 流式请求的审计处理
        return chain.nextAroundStream(request);
    }
}

注册自定义 Advisor:

java 复制代码
@Bean
public ChatClient auditedChatClient(ChatClient.Builder builder,
                                     AuditRepository auditRepo) {
    return builder
        .defaultAdvisors(new AuditAdvisor(auditRepo))  // 自定义 Advisor
        // ToolCallingAdvisor 和 StructuredOutputValidationAdvisor
        // 会自动注册,无需手动添加
        .build();
}

九、与社区扩展的协同

Spring AI 2.0 的架构为社区扩展提供了坚实基础:

9.1 spring-ai-session(事件溯源会话记忆)

替代内置 ChatMemory 的事件溯源方案,支持:

  • 所有消息类型(包括工具调用,在工具循环中安全使用)
  • 可插拔的上下文压缩策略(含 LLM 摘要)

9.2 spring-ai-agent-utils(Agent 工具集)

基于 2.0 Advisor 架构的生产级 Agent 原语:

  • Agent Skills(AgentSkills 规范的 Spring AI 原生实现)
  • 文件、Shell、Web Fetch、Task、Auto-Memory 等工具
java 复制代码
/**
 * 集成社区扩展的完整配置示例
 */
@Configuration
public class FullStackAgentConfig {

    @Bean
    public ChatClient fullStackClient(
            ChatClient.Builder builder,
            SessionManager sessionManager) {

        return builder
            .defaultAdvisors(
                // 事件溯源会话记忆
                new SessionMemoryAdvisor(sessionManager),
                // Agent Skills 支持
                new AgentSkillsAdvisor()
            )
            .build();
    }
}

十、迁移指南:从 1.x 到 2.0

10.1 必做项

  1. 升级 Spring Boot 到 4.0+
  2. 移除配置中的 .options 前缀
  3. 检查 Options 创建方式:构造函数 → Builder
  4. 处理 Null 安全注解:JSpecify 可能暴露之前隐藏的 NPE 风险

10.2 推荐项

  1. 将自定义工具循环迁移到 Advisor 模式
  2. 评估 MCP 传输方式(Streamable HTTP vs 无状态模式)
  3. 启用 StructuredOutputValidationAdvisor 提升输出质量
  4. 考虑 ToolSearch 优化大规模工具场景的 Token 消耗

10.3 破坏性变更清单

变更 影响 迁移方式
Options 不可变 无法运行时修改 用 Builder 创建新实例
模型变体合并 某些 Azure/HTTP 专用类移除 统一使用 SDK 实现
SSE 传输废弃 MCP SSE 客户端不再工作 切换到 Streamable HTTP
Jackson 3 部分自定义序列化器不兼容 参考 Jackson 3 迁移指南

十一、总结与展望

Spring AI 2.0 GA 标志着 Java AI Agent 开发进入新阶段:

  • Advisor 链让 Agent 行为完全可编程、可观测、可审计
  • MCP 2.0 让 Java 应用无缝融入全球 AI Agent 生态
  • ToolSearch 解决了大规模工具场景的 Token 效率问题
  • Null 安全 + 不可变 Options 提升了代码质量和开发体验

对于 Java 开发者来说,现在是将 AI Agent 能力融入企业应用的最佳时机。Spring AI 2.0 提供了从原型到生产的完整路径,而且它运行在你已经熟悉的 Spring Boot 生态之上。

上图展示了从 1.x 迁移到 2.0 的分阶段路径。每个阶段独立推进,按自己的节奏采用即可。


版权声明:本文内容为原创,基于 Spring 官方博客及 GitHub 公开资料独立撰写。文中示例代码可自由使用于学习和个人项目。转载或引用请注明出处。

参考来源