在 Spring Boot 版本选择这件事上我从 2.7 时代一路跟到现在的 3.5最大的感受就是版本号背后藏着的是框架作者对企业级稳定性和新特性激进程度之间的一次次权衡。很多团队还停在 2.7.x 或者刚升到 3.2.x 的时候Spring Boot 已经默默把 3.3、3.4、3.5 三个版本铺成了三条不同的路——有的适合老项目稳定迁移有的适合新项目尝鲜有的则是从架构层面为云原生环境提前铺路。这篇不是简单的版本发布说明摘抄也不是照着官方文档念一遍 New Features。我想从实际选型和使用场景出发把 Spring Boot 3.3.x、3.4.x、3.5.x 这三个版本在做的事、踩过的坑、迁移时真正要命的点以及长期运维视角下的演进策略一次性讲透。不管你是维护一个已经在生产的 Spring Boot 3.x 项目还是正准备从 2.x 大版本升级或者是在新项目立项时纠结到底用哪个版本起步这篇都值得你花十分钟认真看一遍。1. 三兄弟的背景差异Spring Boot 3.3 / 3.4 / 3.5 到底在解决什么问题先说一个很多开发者容易忽视的事实Spring Boot 的版本节奏是固定的每半年一个大版本每年两个。但每一个版本的时代背景和任务是完全不同的。3.3.x 是稳字当头3.4.x 是承上启下3.5.x 则明显带着为下一个五年做架构铺垫的味道。1.1 为什么会有三个版本并行的混乱期很多团队在选版本时看到 Maven Central 上同时存在 3.3.x、3.4.x、3.5.x第一反应是这仨有什么区别是不是越新越好——大错特错。站在这三个版本的发布背景看Spring Boot 3.3.x 发布于 2024 年年中核心任务是让 Spring Framework 6.1 体系下的应用稳定落地。它主要修复了大量 3.2 引入的 AOT 相关编译问题并补全了可观测性、安全性和配置属性的边缘 Case。Spring Boot 3.4.x 发布于 2024 年 11 月给人的感觉是结构整理版。大量配置属性和三方库依赖版本被集中调整并且加入了 Structured Logging结构化日志、HTTP Client 相关的更细粒度配置同时开始强制推动某些 API 的废弃。Spring Boot 3.5.x 发布于 2025 年中最明显的变化是底层升级到了 Spring Framework 7并且把 Jakarta EE 的版本基线、依赖管理和模块化边界都重新梳理了一遍。这里有一个很重要的点Spring Boot 3.5.x 不是 3.4.x 的小步快跑而是基于 Spring Framework 7 的一次基线跳跃。这意味着它虽然兼容大部分 3.x 的 API但在某些底层行为、条件装配和模块边界上会出现连带变化。1.2 从使用者视角看三个版本的核心价值如果我是一个正在做技术选型的开发者我不会去背官方 Release Notes我会用三个维度去判断维度Spring Boot 3.3.xSpring Boot 3.4.xSpring Boot 3.5.x底层框架Spring Framework 6.1.xSpring Framework 6.2.xSpring Framework 7.0.x核心定位稳定性修复与经验积累配置结构与 API 整理新架构基线与云原生能力升级迁移友好度高对 3.2 用户几乎无缝中配置变更多但自动迁移工具覆盖面大低涉及底层依赖边界变化新特性侧重可观测性、AOT 稳定性结构化日志、HTTP Interface 完善模块化边界、依赖基线升级、虚拟线程强化长期支持按常规策略推测OSS 支持约到 2026 年中约到 2027 年中约到 2028 年之后表格里的长期支持是参考 Spring 官方对 OSS 版本的常规支持周期推算的具体以官方生命周期公告为准。但我们可以确定一件事如果你的项目生命周期超过一年半选择 3.3.x 而没有任何升级计划那么在 2026 年下半年之后会遇到社区停止修补安全漏洞的情况这个问题会在后面单独讲。1.3 项目正文里没明说但必须懂的隐含选择逻辑从项目标题和热词搜索的内容来看很多人的痛点并不是这三个版本长什么样而是我手上这个项目应该选哪个以及从 2.7 直接跳到 3.5 是不是可行。这背后隐含的其实是三件事依赖生态的适配度很多第三方组件比如某些老牌 ORM 扩展、私有化中间件客户端仍然没有跟上 Spring Framework 7 的模块边界变化直接上 3.5.x 可能会导致运行时 NoClassDefFoundError 或组件扫描失效。团队的迁移成本3.4.x 和 3.5.x 在配置属性上的大量废弃与更名意味着团队里需要有人专门负责配置迁移否则会出现一堆配置属性不存在的启动报错。业务系统的长期演进如果公司内部有一套统一的微服务平台那么版本选择不是一个项目的事而是所有业务线共用的基线。这个时候 3.3、3.4、3.5 的差异会直接影响公司内部的脚手架、公共组件和 CI/CD 模板。接下来的部分我会按照从 3.3 逐步看起、逐个讲透、最后给出演进策略的思路展开把每个版本里那些 Release Notes 里没有写透的细节掰开揉碎讲清楚。2. Spring Boot 3.3.x稳定压倒一切但别指望它包治百病如果你现在维护的是一个已经在生产的 Spring Boot 3.2.x 项目那么 3.3.x 绝对是成本最低的升级目标。这一节我重点聊它做了什么、哪些地方适合长期停留、哪些地方又必须尽快离开。2.1 3.3 的稳定性回归AOT 与原生镜像的补课Spring Boot 3.x 最大的架构变化其实是拥抱 GraalVM 原生镜像但 3.2 时代这个能力并不成熟。我自己在一个内部工具型项目中尝试过用 Spring Boot 3.2 GraalVM 做原生编译遇到的最典型的两个问题是某些反射调用在编译期无法被静态分析捕获运行时报错说不清道不明配置属性类在 AOT 阶段没有被注册导致启动时一堆The following 1 profile is active和Configuration properties are not registered警告。到了 3.3.x官方在 Spring Framework 6.1 的 AOT 引擎上做了大量修补最直观的感受是配置属性的ConfigurationProperties扫描更完整了GraalVM 原生编译时的错误提示从一堆抽象描述变成了明确的类名和字段名。如果你有原生镜像需求3.3.x 是一个比 3.2 舒服得多的起点。在 JVM 模式下的稳定性提升也很明显。我在一个高并发短任务场景中从 3.2 升到 3.3 后最明显的感知是Scheduled任务在线程池耗尽时的异常处理行为变得更符合直觉不会因为个别任务抛异常就导致整个调度器静默卡住。这个变化在 Release Notes 里只是一句话但在真实线上环境中价值极高。2.2 适合选择 3.3.x 的典型场景不是所有项目都需要最新也不是所有项目都应该勇闯新版本。根据我在多个实际项目里的观察3.3.x 适合这几类场景存量 3.2 项目如果你的项目没有严重的技术债只是想获得关键 Bug 修复3.3.x 是最好的小而稳升级。重度使用第三方库某些中间件客户端包括但不限于消息队列 SDK、分布式事务组件、私有云网关 SDK验证过的最高版本往往是 3.2 或 3.3升级到 3.4 或 3.5 之前必须等这些组件厂商跟进。对虚拟线程持观望态度的团队3.3.x 里虚拟线程Virtual Threads可以使用但生产级最佳实践还不像 3.4/3.5 那么明确保守团队可以在这里先热身。2.3 3.3 的边界哪些地方明显落后如果你的项目从零开始我其实不推荐直接用 3.3.x 起步除非你的团队对稳定性有极其苛刻的要求。原因在于 3.3.x 有几个明显的时代局限对结构化日志的支持还停留在通过 Logback 自定义 Pattern 实现的水平不像 3.4.x 那样有内置的 Structured Logging 格式支持。对 HTTP InterfaceSpring 6 新增的声明式 HTTP 客户端的支持可以用但不够完善部分响应处理场景需要额外的RestClient代码兜底。底层仍然是 Spring Framework 6.1模块边界没有 Spring Framework 7 那么清晰对 Java 模块化JPMS的适配依然有限。我的建议很简单3.3.x 是一个现在很稳、未来有期限的版本适合存量系统平滑过渡不适合作为新项目三五年的技术底座。3. Spring Boot 3.4.x结构重组的过渡版本配置迁移务必当心如果说 3.3.x 是修修补补那么 3.4.x 就是一次典型的内部装修。这一节我重点讲一个主题为什么升级到 3.4 时你大概率会遇到一堆配置文件报警以及如何降低这种爆炸式迁移的痛苦。3.1 结构化日志与配置属性演进3.4 的两个门面变化Spring Boot 3.4.x 最吸引眼球的新特性是结构化日志Structured Logging。它可以直接输出 JSON 格式的日志让日志系统比如 ELK、Loki 等不需要再在采集端做 Grok 解析。对团队来说这确实是个好消息没有了日志格式不一致的家庭矛盾。但这里有个陷阱许多团队为了用结构化日志在 logback-spring.xml 里做了大量自定义过滤器升级到 3.4 后这些自定义逻辑和内置的结构化日志支持会产生优先级冲突。我见过最典型的场景是明明配置了logging.structured.format.fileecs但输出的还是旧格式排查到最后发现是 logback-spring.xml 里的自定义 PatternLayout 覆盖了默认行为。这不是 Spring Boot 的 Bug而是配置分层导致的预期偏差。配置属性方面的变化更大。Spring Boot 3.4 把很多名字含糊的配置项做了整理比如与数据源、线程池、日志相关的若干属性被统一了命名空间。官方的spring-boot-properties-migrator可以帮你自动迁移大部分旧属性但一定要在升级过程中保留迁移报告不要手滑删掉。迁移报告里列出的 deprecated 属性往往比你想的多得多。3.2 升级到 3.4.x 的实操路径与团队协作要点对于从 3.3 升到 3.4 的项目我的建议路径是这样的先升级 Spring Boot 版本但暂时保留旧配置属性。让 Spring Boot 启动时打印出弃用警告把所有警告收集到一个文件里。应用自动属性迁移。引入spring-boot-properties-migrator依赖后再次启动让它尝试帮你重写旧配置。人为审查剩余警告。自动迁移不能解决所有问题特别是同一个配置属性在多个地方被定义的冲突场景必须人肉判断优先级。删除迁移器依赖。迁移完成后一定要移除spring-boot-properties-migrator否则它会在每次启动时额外执行属性迁移逻辑浪费不必要的启动时间也掩盖后续新增的弃用配置。团队协作层面的建议是不要在一个大版本升级里同时混入代码结构重构、依赖大版本升级和配置迁移。我见过一个团队在升级 3.4 的同时升级了 MyBatis 版本并重构了数据源配置结果 3.4 的配置迁移器把新数据源配置也当成旧格式给重写了排查了很久才分清是人祸还是版本锅。3.3 3.4.x 适合哪些项目使用3.4.x 最适合的是即将开始长线发展、需要稳定但又不希望太落后的团队。它的特点决定了它处于Best of Both Worlds的位置相比 3.3它有更多新特性结构化日志、更好的 HTTP Client 配置、更清晰的配置体系相比 3.5它的迁移风险低很多因为底层仍然是 Spring Framework 6.2而不是面向未来的 7.x。如果你正在做一个预计生命周期 2~3 年的企业内部系统3.4.x 是少折腾且不太旧的版本。但注意这里的前提是团队愿意在升级到 3.4 时花一到两天做配置清理而不是直接把 3.3 的 application.yml 原封不动搬上去。4. Spring Boot 3.5.x背靠 Spring Framework 7云原生时代的架构分水岭到了 3.5.x语境完全变了。它不再是一个功能增量版本而是一个基线升级版本。如果你关注过 Spring Framework 7 的演进方向就会发现 3.5.x 从底层就开始拥抱模块化、可观测性和虚拟线程的最佳实践。这一节我把它的变化拆成底层架构和实际编码体验两层来看。4.1 Spring Framework 7 带来的底层变化不是升级而是换代Spring Framework 7 对模块边界的梳理是近几年最伤筋动骨的一次。最直观的影响是spring-beans 和 spring-core 的包结构发生了内部调整大量org.springframework.core下的类被移动到org.springframework.core.metrics、org.springframework.core.env等更细的子包中。如果你是自定义框架组件的开发者升级到 3.5 后你写的很多import语句都会面临失效。另外Spring Framework 7 明确要求JDK 17 是起步基线并且对 JDK 21 的虚拟线程做了更好的线程池桥接。在 3.4 里spring.threads.virtual.enabledtrue已经能让 Tomcat 使用虚拟线程但一些底层异步任务比如Async注解的默认执行器仍然走的是 Platform Thread。到了 3.5整个任务执行体系的默认线程池设计已经按虚拟线程的语义重新考量类加载和线程工厂的扩展点也变了。如果从这个角度看3.5.x 是不是比 3.4 强很多就不太准确——它更像是一台重新装潢过并且改了地基的房子你不能只刷墙必须重新检查承重结构。4.2 模块化边界与依赖管理的变化第三方组件面临的生死局我前面提到了第三方中间件 SDK 的适配问题。在 3.5.x 里这一问题的严重程度会被放大。原因有三个Spring Framework 7 提升了某些模块的编译基线一些用旧 Java 版本编译的第三方库在运行时可能因为UnsupportedClassVersionError直接起不来。模块边界的变化让类可见性问题更加尖锐。以前很多库故意用org.springframework.util的内部实现来做某些 hack在 3.5 里这些内部类很可能变成 module-private直接编译不过或运行时报IllegalAccessError。Gradle 和 Maven 的依赖解析策略也在 Spring Boot 3.5 的依赖管理 BOM 中做了调整部分传递依赖的范围变了。我建议任何准备升级到 3.5.x 的团队第一步不是改代码而是先做一个全量依赖清单扫描。具体操作是生成当前项目的dependency:tree把每个第三方库和它的版本全部列出来对照该库的 Release Notes 或 GitHub Issues搜索是否有Spring Framework 7 compatibility相关的工作先在一个分支上升级 Spring Boot 到 3.5.x然后启动一次应用记录所有 ClassNotFound / NoSuchMethodError / IllegalAccessError再逐个与第三方库的版本对照。这个过程看似繁琐但比起直接合并到主干里炸一片前期半小时的检查能省掉后期一整周的线上事故排查。4.3 3.5.x 里的虚拟线程与可观测性真正的生产级体验虚拟线程在 Spring Boot 3.2 里是可以用但管够小心的状态到了 3.5 有了质的飞跃。具体体现在默认的阻塞任务适配更好。虚拟线程最怕的是在线程内部调用synchronized或 JNI 方法导致 pinning3.5 对 Tomcat 和 JDK 自带 HttpClient 的虚拟线程亲和度做了更多内建优化。可观测性信号的线程上下文传递更完整。在虚拟线程大量复用的场景下传统的ThreadLocal传递会出现数据混乱。Spring Boot 3.5 中的 Micrometer Tracing 和分布式日志链路在虚拟线程间的上下文传播策略更加成熟org.springframework.core.task.VirtualThreadTaskExecutor的行为也更好预测。如果你的系统是一个 IO 密集型的 API 网关、数据同步服务或者外部接口聚合层那么在 3.5.x 上开启虚拟线程值得一试。但请记住虚拟线程不是万灵药如果你的业务代码里到处都是 CPU 密集计算或重量级锁虚拟线程可能不会带来预期收益甚至会因为上下文切换而增加开销。4.4 什么时候选择 3.5.x 作为新项目的起点我把新项目的选择标准整理成这几条团队已经有一定 Spring Boot 3.x 经验不害怕处理模块边界问题依赖的中间件 SDK 都确认支持 Spring Framework 7项目对虚拟线程、结构化日志、云原生可观测性有明确需求团队愿意跟着版本节奏做持续升级而不是把一个版本用五年。如果上述条件全部满足3.5.x 是一个面向未来的好选择。但如果你的项目高度依赖某闭源组件且它没有明确的 3.5 适配计划那我建议你宁可先停在 3.4也不要强行 3.5——框架新版本带来的收益远没有一个稳定运行的核心业务重要这个优先级必须搞清楚。5. 从 2.7 到 3.5 的跨版本升级路线每一步的风险与应对很多团队还在用 Spring Boot 2.7.x而 2.7 的 OSS 支持已结束很久了安全漏洞的社区修复路径基本关闭。如果你现在不得不动那么2.7 → 3.5看起来是大跨步实际上一口吃不成胖子。这一节我给出一个分阶段的升级地图。5.1 为什么不能直接从 2.7 跳到 3.5四道必须跨过的门槛把 2.7 直接升级到 3.5要同时面对四件事Jakarta EE 命名空间迁移javax.*换成jakarta.*。这一项不只是改 import还涉及第三方库内部的静态引用必须确认所有依赖的新版本已经完成命名空间迁移。Spring Security 6 / Security 7 的配置 DSL 重构2.7 时代的WebSecurityConfigurerAdapter完全废弃你需要用SecurityFilterChainBean 的方式重写安全配置。配置属性的全面重命名从 2.7 到 3.5配置属性经历了多次重命名你必须从 3.3 的迁移器一路用到 3.5 的迁移器逐版本清理。内嵌服务器与底层运行时基线变化Tomcat 10.1 与 Jetty 12 等带来了 Servlet 6.0 规范的实现差异某些基于 Servlet 3.0/4.0 API 的过滤器、监听器代码会直接不兼容。这四点单独拆开处理都不算特别难但合在一起就像一个连环雷。如果不在中间层做缓冲一旦启动失败复杂到根本无法快速定位。5.2 推荐的三段式升级策略2.7 → 3.3 → 3.4/3.5我在多个项目中实践下来最稳妥的路径是第一段2.7.x → 3.3.x。这是最难过的一段。先把 Jakarta、Security、配置属性全部搞定。3.3 作为迁移目的地能让你在最新稳定 API 的基础上消化 3.x 的行为变化。第二段3.3.x → 3.4.x。利用spring-boot-properties-migrator清理配置属性并把结构化日志等新能力逐步引入。这一步可以小范围灰度。第三段3.4.x → 3.5.x。这一步前先做好第三方组件兼容性扫描。如果一切通过再到测试环境完整回归。这个策略的关键在于每一段升级后都留出足够的观察期而不是两周内连续升三个大版本。每个中间状态都应该是可稳定上线的状态这样就算后续阶段失败你也可以随时停在当前版本恢复生产不至于陷入回不去的中间态。5.3 测试环节的增量设计升级不是改个版本号就行版本升级回归测试往往被压缩但以下这些点你是不能省的启动测试配置属性、自动配置类是否有冲突。接口契约测试Spring MVC 的错误响应结构、参数绑定行为在不同版本可能有细微差异。安全测试Spring Security 的默认 CSRF、CORS、Session 策略可能在升级后有不同的默认值。异步与调度测试线程池命名、拒绝策略、虚拟线程开关对现有异步任务的影响。可观测性测试如果接了 Prometheus、OpenTelemetry要检查指标名、标签、Trace 上下文在升级后是否一致。用总结性的话说版本升级的测试重点不是新功能能不能用而是旧功能有没有被悄悄改掉。这是最容易忽视也最容易出问题的地方。6. 长期演进策略选择一个版本之后如何规划未来的升级节奏版本选择从来不是一次性决策而是一个滚动过程。我见过很多团队在选定一个版本后彻底躺平直到某天中间件爆出高危漏洞或者新入职的同事发现我们项目连 Java 21 都用不了才开始焦虑。这时候再升级成本已经比定期小版本升级高出很多倍。这一节我聊聊更长期视角的版本管理策略。6.1 用窗口期思维替代版本固定思维版本固定思维是选一个版本然后用它到天荒地老。窗口期思维是知道当前版本的 OSS 支持截止时间然后在支持截止前半年到一年内规划下一次升级。这样做的好处是你有足够的时间做升级准备而不是被安全漏洞追着跑你的团队成员始终处于最近一个或两个版本的知识范围内不会出现老员工只会 2.7新员工只会 3.5的知识断层你可以在相对从容的状态下评估每一次升级的技术收益和成本而不是被迫升级。具体操作上我会在每个季度末做一次版本健康检查打开 Spring 官方支持页面找出当前 Spring Boot 版本的上游支持截止时间再对比团队当前的迭代计划。如果支持截止时间距离当前时间不足 12 个月就把它纳入下个季度的技术债务清理项明确负责人和期望完成时间。6.2 建立团队内部的版本升级 check list与自动化检查花时间把升级流程沉淀成团队文档比每次临时抱佛脚看 Release Notes 高效得多。建议包含这几项升级前依赖兼容性扫描、配置属性迁移报告生成、目标版本 Release Notes 高亮阅读。升级中从低到高逐版本执行、每个版本至少一轮冒烟测试、保留可回滚的发布版本。升级后观察内存、CPU、GC 与线程相关指标至少一周确认无异常后关闭快速回滚通道。另外可以在 CI 流水线里加一个版本健康检查任务定期检查当前 Spring Boot 版本是否已经超出或接近 OSS 支持日期并在企业内部的监控群里推送提醒。这种自动化的兜底比任何人为记忆都靠谱。6.3 我的实际选择逻辑总结讲了这么多最后分享一下我个人目前的选型习惯给还没有方向的朋友作参考内部管理系统、生命周期短、追求零迁移成本选 3.3.x但没有长期支持计划的一定要记得在截止日期前安排升级。新业务系统、预计迭代 3 年、希望用到结构化日志和更完善的 HTTP 客户端选 3.4.x。云原生基础设施、微服务数量多、团队版本迭代能力强选 3.5.x并持续关注 Spring Framework 7 系列的小版本更新。任何情况下都不要让项目的 Spring Boot 版本超出官方 OSS 支持时间超过半年否则你等于在裸奔。版本选择没有标准答案但有一条铁律你选的版本必须与你的业务生命周期、团队维护能力、依赖生态成熟度三者对齐。抛开这三者谈哪个版本最好都是不成立的。7. 迁移实践中的高频踩坑点来自真实项目的十个问题最后这部分我整理一下在 3.3/3.4/3.5 迁移和混部过程中实际遇到、或者同行交流中反复被提到的踩坑点。这些点不在官方迁移指南里但遇到时非常浪费时间。7.1 配置属性迁移器带来的假成功在 3.3 升 3.4 时spring-boot-properties-migrator会把server.tomcat.*之类属性自动改写但当某个属性同时存在于配置文件和环境变量时迁移器可能只改了配置文件环境变量里的旧属性仍然生效而且启动日志里没有告警。排查时会发现我明明改了配置但没生效的现象。应对方式升级时统一检查所有配置来源包括环境变量、配置中心、Kubernetes ConfigMap不能只看 application.yml。7.2 Spring Boot 3.5 里ConfigurationProperties的构造绑定变化Spring Framework 7 对不可变配置属性类的构造绑定做了更严格的约束。以前你可以用ConfigurationProperties配合一个全参构造函数 一个无参构造函数实现半绑定在 3.5 里这种行为可能直接启动失败。如果你的实体类大量使用了 Lombok 的DataConfigurationProperties混合写法建议先看看启动日志里是不是有关于构造绑定的 warning更稳妥的做法是统一用ConstructorBinding或设置非 final 字段 setter 的方式。7.3 从 3.4 升 3.5 后RestClient的默认消息转换器顺序变化Spring Boot 3.5 对RestClient和RestTemplate的默认HttpMessageConverter顺序做了调整导致部分接口从返回 XML 变成返回 JSON或反之。如果你的代码依赖了隐式的内容协商比如没指定Accept头升级后出现数据格式突然变了先去检查是不是消息转换器顺序变化导致的。7.4 升级到 3.5 后 Actuator 端点名称变化部分 Actuator 端点的子路径在 3.5 中做了规范化调整比如某些基于旧版命名规则的监控采集器会报 404。建议升级后重新遍历一遍/actuator/**下暴露的所有端点确保与监控平台的采集规则一致。7.5 虚拟线程开启后线程局部变量的幽灵数据如果开启了spring.threads.virtual.enabledtrue又在代码中用了ThreadLocal存放用户上下文在虚拟线程池复用场景下很容易出现上下文串号而且不一定是每次都会串而是偶发性的。这不是奇怪的现象是虚拟线程不能无脑依赖 ThreadLocal 的根本原因。要么改用ScopedValueJDK 21要么确保代码中清理 ThreadLocal 的逻辑绝对可靠。7.6 从 3.3 升级到 3.4 后日志格式莫名多了一行或少了字段3.4 对默认日志 Pattern 做了一些微调如果你依赖 Logback 的默认格式做日志采集可能会在升级后出现字段缺失或新增。建议升级后对比升级前后的日志样例并同步调整日志采集端的解析规则。7.7 Spring Security 6.2 / 7 的authorizeHttpRequests行为差异在 3.5 里Spring Security 从 6.2 过渡到了 6.3具体以 Boot 依赖管理为准部分 ant 风格的路径匹配器行为更严格了。如果你之前在权限配置中同时使用了旧式mvcMatchers和新的requestMatchers混合写法可能导致部分接口意外 403 或意外放行。升级后务必跑一遍完整的权限路由测试。7.8 分层编译与 AOT 的启动时间倒挂在 3.5 里如果你尝试做 GraalVM 原生编译但代码里仍存在大量动态代理、反射、动态类生成可能会发现原生镜像的启动时间比 JVM 模式还慢因为需要额外的初始化逻辑。这个现象在 3.2/3.3 时代不明显但 3.5 的 AOT 处理更严格一旦检查到无法静态化的代码会生成更多的运行时兜底逻辑。7.9 测试环境与生产环境依赖版本不一致很多人升级只在 pom.xml 里改了 Spring Boot 版本却忘了统一测试框架版本如 JUnit 5、Mockito、Testcontainers导致生产正常、测试跑不过或反过来。建议把测试环境的依赖版本也纳入升级验收范围单独建一个升级工作流反而不是小事。7.10 不要忽略 Docker 基础镜像的升级Spring Boot 3.5 基于 Spring Framework 7 构建的应用对 JDK 版本有内置的模块化要求如果你仍然使用eclipse-temurin:17-jre-alpine之类的旧镜像某些模块特别是与虚拟线程、HTTP 客户端相关的可能因为 JDK 版本不一致而产生奇怪问题。升级框架版本的同时记得同步升级基础镜像和构建工具链。8. 写在最后的个人实践体会回头看这三个版本我认为 Spring Boot 3.3 / 3.4 / 3.5 不仅仅是三个可选版本更像是一条从稳定到整理再到演进的完整路线。对我个人而言最犯忌的策略是只盯一个版本号然后无限期停在原地。真正健康的做法是把版本升级看作一个周期性任务而不是一次性项目。如果你现在正在为选哪个版本纠结我的建议是先不要问哪个最流行而是问自己三个问题——这个项目的预期生命周期还有多长团队里有没有人能处理模块边界和依赖兼容性问题你依赖的第三方组件它离最新版本支持还有多远把这三个问题的答案定下来版本选择的答案基本就清楚了。技术选型没有绝对的最优解只有最适合你当前处境的满意解。只要保证程序能稳定运行、团队不迷失、依赖不裸奔你就已经做得很好了。希望这篇从稳定性、架构能力和长期演进策略三个角度展开的对比分析能让你在 Spring Boot 版本选择这件事上少走一些弯路。如果后续你在实际迁移中遇到了别的怪问题也欢迎在评论区和同行一起讨论毕竟这些踩坑经验往往比文档里的官方说明更值钱。