Kotlin + Spring Boot 4 升级记录


Spring Boot 3.2 至 4.0 及 Spring Cloud Consul 升级变更记录

本项目近期完成了基础架构升级,从 Spring Boot 3.2 升级至 Spring Boot 4.0.2,并同步将 Spring Cloud Consul 从 4.x 升级至 5.0.1。本次升级涉及底层框架的跨大版本替换,包含多项破坏性变更。

以下为本次升级过程中的核心变动摘要与代码调整记录。

1. 核心依赖版本变更

构建工具及核心框架组件的依赖坐标与版本号均已更新:

  • Spring Boot: 由 3.2.0 升级至 4.0.2(配套 Dependency Management 升级至 1.1.7)。
  • Spring Cloud Consul: 由 4.1.0 升级至 5.0.1。现改为按需引入 consul-configconsul-discovery
  • 构建工具: Gradle Wrapper 由 8.5 升级至 8.14
  • 序列化组件: Jackson 迈入 3.x 版本,依赖坐标变更为 tools.jackson.module:jackson-module-kotlin:3.0.4
  • gRPC 组件: 废弃社区版 net.devh:grpc-spring-boot-starter,全面迁移至 Spring 官方组件 org.springframework.grpc:spring-grpc-spring-boot-starter:1.0.2

2. gRPC 组件迁移与注入模式变更

引入官方 Spring gRPC Starter 后,gRPC 客户端的配置与依赖注入模型发生了根本性变化。

  • 原逻辑:使用 net.devh 提供的 @GrpcClient("service-name") 注解直接在属性级别进行注入。
  • 现规范:官方组件废弃了自定义属性注解注入。现要求采用 Spring 标准的 @Bean 依赖注入模型。需显式通过 GrpcChannelFactory 创建 Channel,封装为 Stub 后注入容器。

代码适配示例:

// 1. 显式声明 Stub Bean
@Bean
fun remoteServiceStub(channelFactory: GrpcChannelFactory): RemoteServiceGrpcKt.RemoteServiceCoroutineStub {
    val channel = channelFactory.createChannel("remote-service")
    return RemoteServiceGrpcKt.RemoteServiceCoroutineStub(channel)
}

// 2. 业务代码使用标准构造器注入
@Component
class RemoteServiceGrpcReceiver(
    private val stub: RemoteServiceGrpcKt.RemoteServiceCoroutineStub
) {
    // 业务逻辑实现...
}

此外,原 YAML 文件中基于 grpc.client.GLOBAL 的非官方客户端配置项已失效,需统一调整为官方配置结构。

3. Jackson 3 升级与 ObjectMapper 定制范式变更

Spring Boot 4 集成了全新的 Jackson 3,引发了 ObjectMapper 配置方式的重要变更。

  • 核心变更:Spring Boot 内部默认生成的 ObjectMapper Bean 现被框架硬性指定为 @Primary
  • 行为影响:以往通过手动声明 @Bean fun objectMapper(): ObjectMapper 来全量覆盖框架默认实例的做法已失效,自定义的 Bean 会被忽略。
  • 现行规范:定制 Jackson 序列化行为需采用以下两种方式:
  1. 优先通过 application.yaml 中的 spring.jackson.* 属性配置通用参数。
  2. 如需注册自定义 Serializer/Deserializer,需通过实现 Jackson2ObjectMapperBuilderCustomizer 接口对内置 Builder 进行微调,避免直接替换组件。

4. 破坏性 API 变更与代码适配

针对框架底层的 API 变更,代码层面进行了如下适配:

  • RestTemplate 异常处理接口变更ResponseErrorHandlerhandleError 方法签名已更新。现要求传入 URIHttpMethod 作为上下文参数。

  • 适配后public void handleError(URI url, HttpMethod method, ClientHttpResponse response)

  • Spring Security 包路径变更:OAuth2 相关配置类包路径发生移动,已将原 org.springframework.boot.autoconfigure.security.oauth2.resource.OAuth2ResourceServerProperties 更新为 org.springframework.boot.security.oauth2.server.resource.autoconfigure.OAuth2ResourceServerProperties

  • Kotlin 注解目标精确化:由于底层框架反射机制收紧,在 Kotlin 数据类主构造函数上使用注解时,需显式指定作用目标。

  • 适配后:涉及的 @JsonProperty@Qualifier 均已修改为 @param:JsonProperty("...")@param:Qualifier("...")

5. 配置文件规范化

针对 application.yaml 进行了冗余清理与属性修正:

  • Consul 连接配置:废弃了 config: import: "consul:..." 的长文本导入语法,改为直接在 spring.cloud.consul 下声明 hostport 属性。
  • 服务发现声明:清理了启动类上冗余的 @EnableDiscoveryClient 注解(已支持自动装配),并移除了 YAML 中的废弃配置项 ip-address