bigywater.tech
Spring · 149

Boot 4 里静默失效的配置属性:旧 key 逐个实测

Spring Boot 4 升级后,哪些 application.properties 里的旧 key 悄悄不生效了?启动会不会报错?properties-migrator 能抓到几个?这篇扫描 3.5.16 与 4.0.8 的配置元数据并逐个实测。

153 个
3.5.16 里有效的 1983 个属性里,在 4.0.8 失效的个数:50 个不再声明、103 个标 error 级弃用
message=null
server.error.include-message=always 在 4.0.8 上无效,/boom 响应的 message 字段仍然是 null,启动日志没有任何提示
6 / 12 → 12 / 12
迁移器只带 web、actuator 时抓到 12 个有替换名的旧 key 里的 6 个,补上这些 key 所属的模块后抓到 12 个

数字

实测 · 本机执行输出
  3.5.16 声明了 2463 个属性,4.0.8 声明了 2613 个
  3.5.16 里还有效的(没有标 error 级弃用)有 1983 个;到了 4.0.8:
    完全不再声明的:50 个
    仍然声明、但标成 error 级弃用(已经不起作用)的:103 个,其中有替换名的 71 个、没有替换名的 32 个
    合计 153 个,约占 7.7%

3.5 里有效的 1983 个属性里,153 个在 4.0.8 失效。

分布

实测 · 本机执行输出
  不再声明的(按前两段):server.undertow(24)、management.signalfx(9)、spring.flyway(6)、spring.session(4)、spring.codec(2)、management.endpoints(1)、management.observations(1)、management.server(1)
  error 级弃用的(按前两段):management.wavefront(24)、management.otlp(14)、spring.data(13)、server.error(7)、management.tracing(7)、spring.session(6)、server.servlet(5)、management.zipkin(5)、spring.test(4)、spring.rabbitmq(3)
  有替换名的例子(旧 → 新):
    server.error.include-message → spring.web.error.include-message
    server.servlet.encoding.charset → spring.servlet.encoding.charset
    spring.session.redis.namespace → spring.session.data.redis.namespace
    spring.rabbitmq.listener.simple.retry.max-attempts → spring.rabbitmq.listener.simple.retry.max-retries
    management.tracing.enabled → management.tracing.export.enabled
    management.zipkin.tracing.endpoint → management.tracing.export.zipkin.endpoint
    spring.data.mongodb.uri → spring.mongodb.uri
    spring.graphql.path → spring.graphql.http.path
    management.health.probes.enabled → management.endpoint.health.probes.enabled
    spring.dao.exceptiontranslation.enabled → spring.persistence.exceptiontranslation.enabled
    spring.kafka.retry.topic.backoff.random → spring.kafka.retry.topic.backoff.jitter
  没有替换名的例子:spring.freemarker.enabled、spring.groovy.template.enabled、spring.jackson.generator、spring.jackson.parser、spring.mustache.enabled、spring.neo4j.pool.metrics-enabled
  完全没声明的例子:server.undertow.threads.worker、server.undertow.max-http-post-size、spring.flyway.clean-on-validation-error、spring.codec.max-in-memory-size、management.signalfx.metrics.export.enabled、management.endpoint.conditions.enabled

失效的 key 集中在 undertow、wavefront、otlp、spring.data.mongodb、server.error、tracing、session 等前缀,多数有替换名。

静默失效

实测 · 本机执行输出
  3.5.16 / 什么都不设:/boom → 500,message=null,exception=null;/enc 的 Content-Type=text/plain;charset=ISO-8859-1
  3.5.16 / 旧 key:/boom → 500,message="内部细节 secret-detail",exception="java.lang.IllegalStateException";/enc 的 Content-Type=text/plain;charset=UTF-8
  4.0.8 / 什么都不设:/boom → 500,message=null,exception=null;/enc 的 Content-Type=text/plain;charset=ISO-8859-1
  4.0.8 / 旧 key:/boom → 500,message=null,exception=null;/enc 的 Content-Type=text/plain;charset=ISO-8859-1
  4.0.8 / 新 key:/boom → 500,message="内部细节 secret-detail",exception="java.lang.IllegalStateException";/enc 的 Content-Type=text/plain;charset=UTF-8
  旧 key 在 4.0.8 的启动日志里有没有提到它们:False;日志共 62 行

旧 key 在 4.0.8 上没有效果,启动日志没有提示;新 key 才生效。

迁移器

实测 · 本机执行输出
  写进 application.properties 的 30 个旧 key:error 级弃用,有替换名:12、error 级弃用,没有替换名:2、4.0 里仍有效:10、4.0 里完全没声明:6
  (a)classpath 只有 web、actuator 和 migrator:
  退出码 0;日志里有「have been renamed」段 1 个(级别 WARN)、「no longer supported」段 1 个(级别 ERROR);点名的 key 共 6 个
    「renamed」段里的 key 3 个:management.health.probes.enabled、server.servlet.encoding.charset、server.servlet.encoding.force;「no longer supported」段里的 key 3 个
    error 级弃用,有替换名:共 12 个,被点名 6 个;没被点名的:spring.session.redis.namespace、spring.rabbitmq.listener.simple.retry.max-attempts、management.tracing.enabled、management.zipkin.tracing.endpoint、spring.data.mongodb.uri、spring.graphql.path
    error 级弃用,没有替换名:共 2 个,被点名 0 个;没被点名的:spring.freemarker.enabled、spring.thymeleaf.enabled
    4.0 里仍有效:共 10 个,被点名 0 个;没被点名的:spring.jackson.parser.allow-comments、server.port、spring.datasource.hikari.maximum-pool-size、spring.jpa.open-in-view、server.tomcat.threads.max、spring.mvc.async.request-timeout、spring.flyway.enabled、management.endpoint.health.show-details、spring.application.name、logging.level.root
    4.0 里完全没声明:共 6 个,被点名 0 个;没被点名的:server.undertow.threads.worker、server.undertow.max-http-post-size、spring.flyway.clean-on-validation-error、spring.codec.max-in-memory-size、management.signalfx.metrics.export.enabled、management.endpoint.conditions.enabled
  (a)里点名的 Reason 举例:Replacement key 'spring.web.error.include-message' uses an incompatible target type、Replacement key 'spring.web.error.include-stacktrace' uses an incompatible target type、Replacement key 'spring.web.e
  (b)classpath 再加上这些 key 所属的模块(session-data-redis、amqp、data-mongodb、graphql、zipkin、thymeleaf、freemarker):
  退出码 0;日志里有「have been renamed」段 1 个(级别 WARN)、「no longer supported」段 1 个(级别 ERROR);点名的 key 共 14 个
    「renamed」段里的 key 5 个:management.health.probes.enabled、server.servlet.encoding.charset、server.servlet.encoding.force、spring.graphql.path、spring.rabbitmq.listener.simple.retry.max-attempts;「no longer supported」段里的 key 9 个
    error 级弃用,有替换名:共 12 个,被点名 12 个
    error 级弃用,没有替换名:共 2 个,被点名 2 个
    4.0 里仍有效:共 10 个,被点名 0 个;没被点名的:spring.jackson.parser.allow-comments、server.port、spring.datasource.hikari.maximum-pool-size、spring.jpa.open-in-view、server.tomcat.threads.max、spring.mvc.async.request-timeout、spring.flyway.enabled、management.endpoint.health.show-details、spring.application.name、logging.level.root
    4.0 里完全没声明:共 6 个,被点名 0 个;没被点名的:server.undertow.threads.worker、server.undertow.max-http-post-size、spring.flyway.clean-on-validation-error、spring.codec.max-in-memory-size、management.signalfx.metrics.export.enabled、management.endpoint.conditions.enabled
  (b)里点名的 Reason 举例:Replacement key 'management.tracing.export.enabled' uses an incompatible target type、Replacement key 'management.tracing.export.zipkin.endpoint' uses an incompatible target type、Replacement key 'spring.web.error.include-message' uses an incompatible target type、Replacement key 'spring.web.error.incl

properties-migrator 依赖 classpath 上的模块元数据,能抓到改名,抓不到已经不存在的 key。

分步演示

配置
本步的对象

    本文用到的工具与边界

    • 本机 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;配置元数据来自 Maven Central 的各模块 jar 里的 META-INF/spring-configuration-metadata.json,3.5.16 取 spring-boot、autoconfigure、actuator-autoconfigure、test-autoconfigure、docker-compose,4.0.8 取 BOM 里全部 130 个 spring-boot-* 模块 jar;「有效」指没有标 error 级弃用;行为实验用同一个 web + actuator 应用在两个版本上各启动一次;迁移器是 spring-boot-properties-migrator;「BOM 里没有 spring-boot-starter-undertow」是翻看 4.0.8 的 BOM 得到的,没有写进实验输出)
    • 没有验证:这 153 个 key 里除了 server.error.*、server.servlet.encoding.* 之外每一个的实际行为(只信元数据里的弃用级别);spring.data.mongodb、spring.session、spring.rabbitmq 等 key 的运行效果(其中 session 与 rabbitmq 在对应专题里单独测过);Gradle、application.yml 与环境变量写法;relaxed binding 下大小写或下划线写法的 key;元数据本身遗漏或错标的属性
    京ICP备2026067502号-1京公网安备11010502063487号