Spring 原生镜像仍用构建配置:环境变量可能指向了占位符别名
process-aot 使用的 profile 会影响原生镜像。若运行时环境变量只改占位符别名,生效的 profile 文档可能已把该占位符整段替换。
Spring Boot 4.0.6 的原生镜像一直使用构建阶段的占位值,容器中的环境变量却确实存在。若 process-aot 启用了专用 profile,先检查最终生效的属性值是否仍含占位符,以及环境变量是否对应真正的属性名。
例如普通文档写的是:
demo:
platform:
defaultless: ${DEMO_DEFAULTLESS}
另一个由 AOT 构建启用的文档又写成:
spring:
config:
activate:
on-profile: aot
demo:
platform:
defaultless: aot-defaultless
这些是两个配置文档的片段,实际项目应保留正确的多文档分隔和原有其他键。aot 文档生效后,同名属性的值已经是字面量 aot-defaultless,不再是 ${DEMO_DEFAULTLESS}。运行时修改 DEMO_DEFAULTLESS,不会让已被覆盖的占位符重新参与求值。
用真实属性名的环境变量覆盖
目标属性是 demo.platform.defaultless,对应的环境变量名为 DEMO_PLATFORM_DEFAULTLESS。在原来获准的启动环境中给它配置真实值,而不是只设置 DEMO_DEFAULTLESS 这个自定义别名。
这条区别不代表环境变量失去优先级,也不能据此判断 @ConfigurationProperties 把构建值永久快照在最高层。应分别核对有效 profile、属性完整名称、当前选中值及实际运行环境。诊断时只输出专用无敏感性的示例属性,不要把生产密码或密钥导出到启动日志。
验收可使用两个不同的非敏感标记值:保持同一原生二进制,分别通过真实属性名的环境变量启动,确认绑定值随之改变。再撤掉必需值,按应用既有校验规则确认它是否如预期拒绝启动或采用明确的默认值。
构建专用值不必放进长期生效的 profile
如果 AOT 只是为了启动分析上下文而需要临时属性,可以评估通过 process-aot 的 jvmArguments 传入构建所需值,避免把仅供构建的字面配置放进运行时也会生效的文档。修改前保留插件配置与原生构建结果,再重新构建验收。
这不能把 AOT 变成可以任意切换结构的 JVM 应用。构建期间由 profile、条件属性决定的 Bean 选择仍有原生镜像约束;运行时改变一个普通绑定值,与重新决定有哪些 Bean 是两回事。若业务确实需要不同结构,应使用对应构建配置产生独立镜像,而不是用环境变量掩盖构建差异。


