bigywater.tech
Spring · 148

Spring Boot 3.5 升到 4.0:只改版本号,会遇到哪些编译和启动错误

Spring Boot 3.5 升级到 4.0,只改版本号会怎样?哪些 import 编译不过、搬到了哪个新包?classic starter 能不能当过渡?这篇在 3.5.16 与 4.0.8 上用同一组 starter 逐个实测。

9 / 32
4.0.8 上还能编译通过的旧 import 个数(3.5.16 上是 32 / 32)
19 个新位置
失败的 23 个里,在 4.0.8 的模块里找到同名类的个数,换新全限定名后全部编译通过
starter-aop 没了
4.0.8 的 BOM 里没有 spring-boot-starter-aop,依赖解析直接失败

换版本

实测 · 本机执行输出
  3.5.16:解析成功,103 个 jar,其中 spring-boot-* 模块 6 个
  4.0.8(去掉 aop 之后的 6 个 starter):解析成功,120 个 jar,其中 spring-boot-* 模块 25 个
  4.0.8 加上 spring-boot-starter-aop:解析失败 → 'dependencies.dependency.version' for org.springframework.boot:spring-boot-starter-aop:jar is missing. @ line 
  4.0.8 里新增的 spring-boot 模块名(3.5 没有同名的)共 19 个,例如:spring-boot-data-commons、spring-boot-data-jpa、spring-boot-health、spring-boot-hibernate、spring-boot-http-converter、spring-boot-jackson、spring-boot-jdbc、spring-boot-jpa
  Jackson:3.5.16:jackson-databind-2.21.4 / 4.0.8:jackson-databind-3.1.5
  Hibernate:3.5.16:hibernate-core-6.6.53.Final / 4.0.8:hibernate-core-7.2.24.Final

同一组 starter 换版本:模块从 6 个变 25 个,starter-aop 消失,Jackson 与 Hibernate 大版本跳变。

旧 import

实测 · 本机执行输出
  3.5.16:通过 32 个,失败 0 个
  4.0.8:通过 9 个,失败 23 个
    失败 MockBean  (org.springframework.boot.test.mock.mockito.MockBean) → package org.springframework.boot.test.mock.mockito does not exist
    失败 SpyBean  (org.springframework.boot.test.mock.mockito.SpyBean) → package org.springframework.boot.test.mock.mockito does not exist
    失败 ObjectMapper  (com.fasterxml.jackson.databind.ObjectMapper) → package com.fasterxml.jackson.databind does not exist
    失败 JsonComponent  (org.springframework.boot.jackson.JsonComponent) → cannot find symbol
    失败 Jackson2ObjectMapperBuilderCustomizer  (org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer) → package org.springframework.boot.autoconfigure.jackson does not exist
    失败 DataSourceProperties  (org.springframework.boot.autoconfigure.jdbc.DataSourceProperties) → package org.springframework.boot.autoconfigure.jdbc does not exist
    失败 HealthIndicator  (org.springframework.boot.actuate.health.HealthIndicator) → package org.springframework.boot.actuate.health does not exist
    失败 AutoConfigureMockMvc  (org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc) → package org.springframework.boot.test.autoconfigure.web.servlet does n
    失败 WebMvcTest  (org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest) → package org.springframework.boot.test.autoconfigure.web.servlet does n
    失败 DataJpaTest  (org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest) → package org.springframework.boot.test.autoconfigure.orm.jpa does not e
    失败 EntityScan  (org.springframework.boot.autoconfigure.domain.EntityScan) → package org.springframework.boot.autoconfigure.domain does not exist
    失败 RestTemplateBuilder  (org.springframework.boot.web.client.RestTemplateBuilder) → package org.springframework.boot.web.client does not exist
    失败 TestRestTemplate  (org.springframework.boot.test.web.client.TestRestTemplate) → package org.springframework.boot.test.web.client does not exist
    失败 PathRequest  (org.springframework.boot.autoconfigure.security.servlet.PathRequest) → package org.springframework.boot.autoconfigure.security.servlet does n
    失败 HttpMessageConverters  (org.springframework.boot.autoconfigure.http.HttpMessageConverters) → package org.springframework.boot.autoconfigure.http does not exist
    失败 ServerProperties  (org.springframework.boot.autoconfigure.web.ServerProperties) → cannot find symbol
    失败 HibernateJpaAutoConfiguration  (org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration) → package org.springframework.boot.autoconfigure.orm.jpa does not exist
    失败 HibernatePropertiesCustomizer  (org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer) → package org.springframework.boot.autoconfigure.orm.jpa does not exist
    失败 WebMvcAutoConfiguration  (org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration) → package org.springframework.boot.autoconfigure.web.servlet does not ex
    失败 ErrorViewResolver  (org.springframework.boot.autoconfigure.web.servlet.error.ErrorViewResolver) → package org.springframework.boot.autoconfigure.web.servlet.error does 
    失败 ErrorAttributes  (org.springframework.boot.web.servlet.error.ErrorAttributes) → package org.springframework.boot.web.servlet.error does not exist
    失败 TransactionProperties  (org.springframework.boot.autoconfigure.transaction.TransactionProperties) → package org.springframework.boot.autoconfigure.transaction does not ex
    失败 CacheManagerCustomizer  (org.springframework.boot.autoconfigure.cache.CacheManagerCustomizer) → cannot find symbol
    通过 FilterRegistrationBean  (org.springframework.boot.web.servlet.FilterRegistrationBean)
    通过 WebServerFactoryCustomizer  (org.springframework.boot.web.server.WebServerFactoryCustomizer)
    通过 ConditionalOnBean  (org.springframework.boot.autoconfigure.condition.ConditionalOnBean)
    通过 SpringBootApplication  (org.springframework.boot.autoconfigure.SpringBootApplication)
    通过 TaskExecutionProperties  (org.springframework.boot.autoconfigure.task.TaskExecutionProperties)
    通过 ConfigurationProperties  (org.springframework.boot.context.properties.ConfigurationProperties)
    通过 SpringBootTest  (org.springframework.boot.test.context.SpringBootTest)
    通过 Endpoint  (org.springframework.boot.actuate.endpoint.annotation.Endpoint)
    通过 WebEndpointProperties  (org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties)

32 个常见 import 在 4.0.8 上只通过 9 个。

搬到哪

实测 · 本机执行输出
    ObjectMapper:com.fasterxml.jackson.databind → tools.jackson.databind  [jackson-databind-3.1.5]
    DataSourceProperties:org.springframework.boot.autoconfigure.jdbc → org.springframework.boot.jdbc.autoconfigure  [spring-boot-jdbc]
    HealthIndicator:org.springframework.boot.actuate.health → org.springframework.boot.health.contributor  [spring-boot-health]
    AutoConfigureMockMvc:org.springframework.boot.test.autoconfigure.web.servlet → org.springframework.boot.webmvc.test.autoconfigure  [spring-boot-webmvc-test]
    WebMvcTest:org.springframework.boot.test.autoconfigure.web.servlet → org.springframework.boot.webmvc.test.autoconfigure  [spring-boot-webmvc-test]
    DataJpaTest:org.springframework.boot.test.autoconfigure.orm.jpa → org.springframework.boot.data.jpa.test.autoconfigure  [spring-boot-data-jpa-test]
    EntityScan:org.springframework.boot.autoconfigure.domain → org.springframework.boot.persistence.autoconfigure  [spring-boot-persistence]
    RestTemplateBuilder:org.springframework.boot.web.client → org.springframework.boot.restclient  [spring-boot-restclient]
    TestRestTemplate:org.springframework.boot.test.web.client → org.springframework.boot.resttestclient  [spring-boot-resttestclient]
    PathRequest:org.springframework.boot.autoconfigure.security.servlet → org.springframework.boot.security.autoconfigure.web.servlet  [spring-boot-security]
    HttpMessageConverters:org.springframework.boot.autoconfigure.http → org.springframework.boot.http.converter.autoconfigure  [spring-boot-http-converter]
    ServerProperties:org.springframework.boot.autoconfigure.web → org.springframework.boot.web.server.autoconfigure  [spring-boot-web-server]
    HibernateJpaAutoConfiguration:org.springframework.boot.autoconfigure.orm.jpa → org.springframework.boot.hibernate.autoconfigure  [spring-boot-hibernate]
    HibernatePropertiesCustomizer:org.springframework.boot.autoconfigure.orm.jpa → org.springframework.boot.hibernate.autoconfigure  [spring-boot-hibernate]
    WebMvcAutoConfiguration:org.springframework.boot.autoconfigure.web.servlet → org.springframework.boot.webmvc.autoconfigure  [spring-boot-webmvc]
    ErrorViewResolver:org.springframework.boot.autoconfigure.web.servlet.error → org.springframework.boot.webmvc.autoconfigure.error  [spring-boot-webmvc]
    ErrorAttributes:org.springframework.boot.web.servlet.error → org.springframework.boot.webmvc.error  [spring-boot-webmvc]
    TransactionProperties:org.springframework.boot.autoconfigure.transaction → org.springframework.boot.transaction.autoconfigure  [spring-boot-transaction]
    CacheManagerCustomizer:org.springframework.boot.autoconfigure.cache → org.springframework.boot.cache.autoconfigure  [spring-boot-cache]
  按同名找到新位置的 19 个,同名类不存在的 4 个:MockBean、SpyBean、JsonComponent、Jackson2ObjectMapperBuilderCustomizer
  用新全限定名在加了对应模块的 classpath 上编译:通过 19 / 19 个

自动配置与测试注解按模块拆开,新包名带模块名;19 个在新位置验证通过。

改名

实测 · 本机执行输出
    MockitoBean  通过  (org.springframework.test.context.bean.override.mockito)
    MockitoSpyBean  通过  (org.springframework.test.context.bean.override.mockito)
    JacksonComponent  通过  (org.springframework.boot.jackson)
    JsonMapperBuilderCustomizer  通过  (org.springframework.boot.jackson.autoconfigure)
  对应关系(旧 → 新):MockBean → MockitoBean、SpyBean → MockitoSpyBean(都在 spring-test 里);JsonComponent → JacksonComponent;Jackson2ObjectMapperBuilderCustomizer → JsonMapperBuilderCustomizer(只验证了这四个新名字存在、能编译)

MockBean、SpyBean、JsonComponent 等换了名字。

classic

实测 · 本机执行输出
  classpath 223 个 jar(多出 103 个),旧 import 通过 9 / 32(没加之前 9)
  新增的 classic 相关 jar:logback-classic-1.5.38、spring-boot-starter-classic-4.0.8、spring-boot-autoconfigure-classic-4.0.8、spring-boot-autoconfigure-classic-modules-4.0.8、spring-boot-starter-test-classic-4.0.8、spring-boot-test-classic-modules-4.0.8
  加了 classic 之后仍然编译失败的 23 个:MockBean、SpyBean、ObjectMapper、JsonComponent、Jackson2ObjectMapperBuilderCustomizer、DataSourceProperties、HealthIndicator、AutoConfigureMockMvc、WebMvcTest、DataJpaTest、EntityScan、RestTemplateBuilder、TestRestTemplate、PathRequest、HttpMessageConverters、ServerProperties、HibernateJpaAutoConfiguration、HibernatePropertiesCustomizer、WebMvcAutoConfiguration、ErrorViewResolver、ErrorAttributes、TransactionProperties、CacheManagerCustomizer

classic starter 不保留旧包名,import 仍要自己改。

启动

实测 · 本机执行输出
  3.5.16:启动成功;GET /hello 不带凭证 → 401;带凭证 → 200 {"msg":"hi","n":1} (application/json);GET /actuator/health → 200 {"status":"UP"}
  4.0.8:启动成功;GET /hello 不带凭证 → 401;带凭证 → 200 {"n":1,"msg":"hi"} (application/json);GET /actuator/health → 200 {"groups":["liveness","readiness"],"status":"UP"}

用不到被改名类的应用可以直接启动;actuator 健康响应多了 groups。

分步演示

升级
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / OpenJDK 21.0.12(Homebrew) / Spring Boot 4.0.8(Spring Framework 7.0.9、Tomcat 11.0.24) / Spring Cloud 2025.1.3;用 javac 编译、java 直接运行,依赖由 Maven 从 Maven Central 解析;数字每次运行会有小幅抖动(对比版本 Spring Boot 3.5.16 与 4.0.8;依赖用同一组 6 个 starter 经 Maven BOM 解析;每个 import 写成单独的 `Class c = 全限定名.class` 文件,在两个 classpath 上用 javac 编译,「搬到哪」一节扫描了额外加入 webmvc、webmvc-test、data-jpa-test、security-test、restclient、aspectj、jackson、flyway 等 starter 之后的全部 jar)
    • 没有验证:升级后运行时配置属性的变化(见专门一篇);这 32 个 import 之外的类;Gradle 构建与 OpenRewrite 自动迁移;官方迁移指南里列出的其他变化;MockBean 迁移到 MockitoBean 之后行为是否完全等价;classic starter 在运行时(自动配置)到底恢复了什么
    京ICP备2026067502号-1京公网安备11010502063487号