Spring Boot 如何处理配置文件中的占位符

yumo6663周前 (08-28)技术文章12

在 Spring Boot 中,处理配置文件中的占位符(placeholders)是一项非常常见且重要的功能。它允许在配置文件中引用其他配置项、环境变量或系统属性,从而实现灵活、动态的配置管理。

一、占位符的基本语法

Spring Boot 使用 {} 或 $ENV_VAR 的语法来表示占位符。

1. ${property.name:default_value}

  • ${...}:引用配置属性。
  • :default_value 是可选的,表示如果属性未定义,则使用默认值。

示例:

# application.yml
app:
  name: MyApp
  version: 1.0
  description: ${app.name} version is ${app.version:unknown}
  home: ${HOME}  # 引用系统环境变量
  temp-dir: ${TEMP_DIR:/tmp}  # 环境变量不存在时使用默认值
# application.properties
app.name=MyApp
app.version=1.0
app.description=${app.name} version is ${app.version:unknown}
app.home=${HOME}
app.temp-dir=${TEMP_DIR:/tmp}

二、支持的占位符来源

Spring Boot 会从多个 PropertySource 中查找占位符对应的值,优先级如下(由高到低):

  • 命令行参数(--server.port=8081)
  • 环境变量(SERVER_PORT=8081)
  • 配置文件(application.yml / application.properties)
  • @PropertySource 注解加载的配置
  • 默认属性(通过 SpringApplication.setDefaultProperties() 设置)

三、在代码中使用占位符

1. 使用 @Value 注解读取

@Component
public class AppConfig {
    @Value("${app.name}")
    private String appName;

    @Value("${app.version:1.0}")  // 提供默认值
    private String version;

    @Value("${HOME}")  // 读取环境变量
    private String homePath;

    // getter...
}

2. 使用 @ConfigurationProperties 绑定(推荐)

更推荐使用类型安全的配置绑定方式。

@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {
    private String name;
    private String version = "1.0"; // 默认值可在代码中设置
    private String description; // 会自动解析 ${app.name} version is ${app.version}
    private String home;
    // getter & setter
}

注意:@ConfigurationProperties 支持占位符解析(如 ${app.name}),但不支持 SpEL 表达式(如 #{systemProperties['user.dir']}),而 @Value 支持 SpEL。

四、跨配置文件引用

可以在一个配置文件中引用另一个配置文件中定义的属性。

# application.yml
database:
  host: localhost
  port: 5432
  url: jdbc:postgresql://${database.host}:${database.port}/mydb

Spring Boot 会自动解析 ${database.host} 和 ${database.port}。

五、使用环境变量覆盖配置

这是 Spring Boot 的强大之处:无需修改配置文件,通过环境变量即可动态覆盖配置

例如:

export DATABASE_HOST=db-prod.example.com
java -jar myapp.jar

即使 application.yml 中 database.host=localhost,运行时也会使用 db-prod.example.com。

六、高级用法:Profile 特定配置

结合 spring.profiles.active,可以实现不同环境的动态配置。

# application.yml
spring:
  profiles:
    active: dev

---
# application-dev.yml
app:
  name: MyApp-Dev
  debug: true

---
# application-prod.yml
app:
  name: MyApp-Prod
  debug: false


然后在其他配置中引用:

logging:
  level: ${app.debug:INFO}

七、注意事项

  1. 循环引用:避免配置项之间形成循环引用,如:
a: ${b}
b: ${a} # 错误!会导致解析失败
  • 类型转换:@Value 注解支持基本类型转换(如 int, boolean),但复杂类型需自定义 Converter。
  • 延迟解析:某些场景下(如 @ConditionalOnProperty),占位符可能在容器初始化早期就被解析,确保值已加载。
  • 安全性:避免在日志中打印包含敏感信息的配置(如密码),即使使用了占位符。

八、调试占位符解析

如果占位符未正确解析,可以启用 debug 模式查看:

java -jar myapp.jar --debug

或在 application.properties 中:

logging.level.org.springframework=DEBUG

总结

方法

适用场景

是否推荐

${...}

配置文件内引用

强烈推荐

@Value

简单字段注入

@ConfigurationProperties

类型安全的配置绑定

强烈推荐

环境变量

动态覆盖配置

(生产环境必备)

最佳实践

  • 使用 @ConfigurationProperties + @Validated 实现类型安全配置。
  • 利用环境变量实现“一次构建,多环境部署”。
  • 合理使用默认值(:default)提高健壮性。

相关文章

有了这些库,Android 开发效率提升好几倍

在 Android 开发的过程中,每个开发者或多或少的都使用过第三方开源库,使用第三方开源库可以大大减少开发者的精力和时间,从而更好的关注应用本身的业务逻辑。网络相关OkHttp一个处理网络请求的开源...

免装环境!SQLite 可视化神器,Java 开发者速通指南

作为 Java 开发者,你是否常为 SQLite 数据库的操作头疼?手写 SQL 建表、查数据太繁琐,命令行工具交互效率低,第三方库集成又容易踩坑?今天要安利的「DB Browser for SQLi...

数据库关系图设计器:DbSchema 9.4.3

DbSchema是一个面向图表的数据库Windows PC软件,兼容所有关系数据库和许多无SQL数据库,如MySql、Cassandra、PostgreSQL、MongoDB架构可视化、Redshif...

Java中使用MongoDB数据库_java执行mongodb命令

一、Java 实现对 MongDB 的操作1、前提条件除了通过启动 mongo 进程进如 Shell 环境访问数据库外,MongoDB 还提供了其他基于编程语言的访问数据库方法。MongoDB 官方提...

基于Java实现,支持在线发布API接口读取数据库,有哪些工具?

基于java实现,不需要编辑就能发布api接口的,有哪些工具、平台?还能一键发布、快速授权和开放提供给第三方请求调用接口的解决方案。架构方案设计:以下是一些基于 Java 实现的无需编辑或只需少量编辑...

牛哇!MySQL中的日志“binlog”的三种格式这么好玩

MySQL 中的日志比较重要的有 binlog(归档日志)、redo log(重做日志)以及 undo log,那么跟我们本文相关的主要是 binlog,另外两个日志松哥将来有空了再和大家详细介绍。1...