Java 后端面试题库 / 全部题解免费阅读理解原理,有条理地回答

配置加载与覆盖顺序怎样判断?

查看完整题解

参考回答

直接回答

先找同一个键来自哪些属性源,再按当前Boot优先级判断;常见命令行、Java系统属性、环境变量与配置数据的覆盖关系要分清。配置数据内部还有位置、环境与导入规则。不存在“所有外部文件永远低于所有包内profile文件”的通用结论,也不应背旧版17项清单当当前规范。

讲清原理

常见生产属性源中,命令行通常可覆盖系统属性,系统属性可覆盖操作系统环境变量,后者通常高于配置数据;但测试属性、JSON和其他特定来源也有自己的位置。默认属性处于较低层,不能与显式设置等同。

默认配置数据顺序还包括包内普通、包内profile、包外普通、包外profile,后者可覆盖前者;导入位置和自定义加载也会影响结果。PropertySource在刷新阶段加入,对某些早期读取参数可能太晚。

同名配置按属性源优先级覆盖,文件内部还有独立顺序
同名配置按属性源优先级覆盖,文件内部还有独立顺序

例子与易错点

演示会固定几个同名值,验证最终值和来源;它不宣称覆盖所有自定义ConfigData组合。排查时使用可安全暴露的来源信息,不能为了调试看全部配置而公开env端点和密钥。

以下为 Java 21 类成员示例,放入同一外部类中使用,依赖 Boot4.1.2 / Framework7.0.10。仅验证默认属性、系统属性和命令行三层;测试结束恢复原系统属性。

@org.springframework.boot.SpringBootConfiguration
static class PrecedenceApp { }
static String selected(String... args) {
    var app=new org.springframework.boot.SpringApplication(PrecedenceApp.class);
    app.setWebApplicationType(org.springframework.boot.WebApplicationType.NONE);
    app.setBannerMode(org.springframework.boot.Banner.Mode.OFF);app.setLogStartupInfo(false);
    app.setDefaultProperties(java.util.Map.of("lesson16.value","default"));
    var all=java.util.stream.Stream.concat(java.util.stream.Stream.of(
        "--spring.config.location=optional:classpath:/__boot16_empty__/",
        "--spring.main.register-shutdown-hook=false"),java.util.Arrays.stream(args)).toArray(String[]::new);
    try (var context=app.run(all)) { return context.getEnvironment().getProperty("lesson16.value"); }
}

相关题:第 4 题、第 13 题、第 19 题。

这道题,你掌握得怎么样?

掌握程度由你主动标记,阅读和收藏不会自动改变状态。