配置文件的占位符

一、先搞懂:什么是配置文件的占位符?

SpringBoot的配置文件(application.properties/application.yml)里,占位符就是用 ${变量名} 格式留的「空位置」 ,程序启动时,Spring会自动把这个「空位置」替换成实际的有效值

可以把它理解成:配置文件里的填空题${} 是填空题的空框,运行时Spring会自动给这个空框填正确的答案。

二、占位符的核心价值(为什么要用?)

  1. 配置复用:同一个值写一次,多处引用,避免重复编写,后续修改只需改一处,减少出错;
  2. 容错兜底 :可以给占位符设置默认值,如果对应的变量没定义,就用默认值,防止配置缺失报错;
  3. 动态配置 :能引用系统环境变量 (如电脑的JAVA_HOME用户名)、启动命令行参数 (如java -jar时动态传参),实现配置的动态适配。

三、占位符的核心语法

所有占位符的基础格式都是 ${xxx},扩展格式(最常用)是设置默认值

复制代码
${变量名:默认值}
  • 冒号 :分隔符,前面是要找的变量名,后面是默认值;
  • 如果Spring能找到变量名对应的有效值,就用有效值;
  • 如果找不到(变量没定义、值为空),就用默认值兜底。

注意 :冒号 : 后面的默认值可以省略,但若省略且变量无值,程序会启动失败(报IllegalArgumentException),所以实际开发中建议尽量加默认值。

四、典型使用场景

日常开发中,占位符主要用在3个核心场景 ,下面逐个讲解,每个场景都提供「properties + yml」两种配置文件写法(适配不同开发习惯),再搭配Java代码演示如何读取带占位符的配置

前提:新建一个基础SpringBoot项目

只需引入最基础的spring-boot-starter-web依赖即可,用于测试配置读取。

场景1:配置文件内部变量复用(最基础、最常用)

先在配置文件中定义一个基础键值对 ,后续的其他配置通过占位符引用这个键的值,实现一次定义、多处使用。

示例配置
1.1 application.properties 写法
properties 复制代码
# 1. 先定义基础配置(可被后续引用)
app.name=springboot-placeholder-demo
app.version=1.0.0
server.port=8080

# 2. 用占位符引用上面的配置(内部复用)
app.desc=${app.name}的版本是${app.version},运行端口是${server.port}
# 给个默认值的例子:如果app.author没定义,就用「佚名」
app.author=${app.author:佚名}
1.2 application.yml 写法(注意yaml的严格缩进,用2个空格,不要用tab)
yaml 复制代码
# 基础配置
app:
  name: springboot-placeholder-demo
  version: 1.0.0
  # 引用+默认值:author没定义则用「佚名」
  author: ${app.author:佚名}
  # 内部复用多个占位符
  desc: ${app.name}的版本是${app.version},运行端口是${server.port}
server:
  port: 8080
场景2:给占位符设置默认值(容错兜底)

这是实际开发中必用的技巧,用于防止「配置缺失导致程序启动失败」。

比如你想让服务端口默认是8080,但若需要临时改端口,只需显式定义server.port即可,没定义就用默认值:

properties 复制代码
# 没定义server.port的话,自动用8080;定义了就用定义的值
server.port=${server.port:8080}
# 自定义配置:没定义app.env的话,默认是dev(开发环境)
app.env=${app.env:dev}
yaml 复制代码
server:
  port: ${server.port:8080}
app:
  env: ${app.env:dev}
场景3:引用系统环境变量/启动命令行参数(动态配置)

SpringBoot会自动扫描3类值源(按优先级排序),占位符可以直接引用这些值:

  1. 启动时的命令行参数 (如java -jar时加--server.port=9090);
  2. 电脑的系统环境变量 (如Windows的USERNAMEJAVA_HOME,Linux的USERPATH);
  3. 配置文件自身的变量(场景1的内容)。

简单说:不用在配置文件写死值,能从外部动态获取,适合多环境、多机器部署的场景。

示例配置
properties 复制代码
# 引用「系统环境变量」:Windows的用户名(USERNAME)、Java安装路径(JAVA_HOME)
sys.username=${USERNAME}
sys.java-home=${JAVA_HOME}

# 引用「命令行参数」:启动时用--app.mode=prod传参,这里就能获取
app.mode=${app.mode:test}
yaml 复制代码
sys:
  username: ${USERNAME}
  java-home: ${JAVA_HOME}
app:
  mode: ${app.mode:test}

五、如何在Java代码中读取带占位符的配置

配置文件中用占位符定义的配置,最终要在Java代码中读取使用,SpringBoot提供了2种最常用的读取方式,覆盖所有场景:

  1. @Value注解 :适合单个/零散配置的读取,简单直接;
  2. @ConfigurationProperties注解 :适合批量/自定义组配置 的读取(如自定义的app.xxx系列),优雅规范。

下面提供完整的Java代码示例,直接复制到项目中即可运行。

方式1:@Value注解(单个配置读取)

新建一个测试控制器 ,用@Value直接绑定配置项,启动项目后访问接口就能看到占位符填充后的结果:

java 复制代码
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 用@Value读取带占位符的配置
 */
@RestController
public class PlaceholderController {

    // 读取自定义配置(内部复用)
    @Value("${app.name}")
    private String appName;

    @Value("${app.desc}")
    private String appDesc;

    // 读取带默认值的配置
    @Value("${app.author}")
    private String appAuthor;

    // 读取系统环境变量
    @Value("${sys.username}")
    private String sysUsername;

    // 读取可通过命令行传参的配置(默认test)
    @Value("${app.mode}")
    private String appMode;

    @GetMapping("/config")
    public String getConfig() {
        return "【配置读取结果】\n" +
                "应用名称:" + appName + "\n" +
                "应用描述:" + appDesc + "\n" +
                "作者:" + appAuthor + "\n" +
                "当前系统用户名:" + sysUsername + "\n" +
                "运行模式:" + appMode;
    }
}
方式2:@ConfigurationProperties(批量配置读取)

如果自定义的配置是一组 (如app.nameapp.versionapp.desc都属于app组),用这种方式更优雅,无需写多个@Value

步骤1:新建自定义配置实体类
java 复制代码
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 批量绑定app开头的配置(前缀为app)
 * @Component:把这个类交给Spring管理
 * @ConfigurationProperties(prefix = "app"):绑定配置中以app为前缀的所有项
 */
@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {
    // 变量名要和配置中的键名一致(如app.name → name,app.version → version)
    private String name;
    private String version;
    private String desc;
    private String author;
    private String env;
    private String mode;

    // 自动生成getter/setter(必须有,否则Spring无法赋值)
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getVersion() { return version; }
    public void setVersion(String version) { this.version = version; }
    public String getDesc() { return desc; }
    public void setDesc(String desc) { this.desc = desc; }
    public String getAuthor() { return author; }
    public void setAuthor(String author) { this.author = author; }
    public String getEnv() { return env; }
    public void setEnv(String env) { this.env = env; }
    public String getMode() { return mode; }
    public void setMode(String mode) { this.mode = mode; }
}
步骤2:在控制器中注入并使用
java 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class AppConfigController {

    // 注入批量配置的实体类
    @Autowired
    private AppProperties appProperties;

    @GetMapping("/app-config")
    public AppProperties getAppConfig() {
        // 直接返回实体类,Spring会自动转成JSON格式
        return appProperties;
    }
}

六、运行测试(看占位符的填充效果)

1. 直接启动项目(无命令行参数)

启动后访问 http://localhost:8080/config,会看到所有占位符都被自动填充,效果如下:

复制代码
【配置读取结果】
应用名称:springboot-placeholder-demo
应用描述:springboot-placeholder-demo的版本是1.0.0,运行端口是8080
作者:佚名
当前系统用户名:你的电脑用户名(如Administrator)
运行模式:test

访问 http://localhost:8080/app-config,会看到JSON格式的批量配置结果,占位符同样被填充。

2. 带命令行参数启动(动态修改配置)

把项目打成jar包(mvn clean package),用以下命令启动(动态传参--app.mode=prod--server.port=9090):

bash 复制代码
java -jar 你的项目包名.jar --app.mode=prod --server.port=9090

启动后访问 http://localhost:9090/config,会看到命令行参数覆盖了默认值

复制代码
运行模式:prod (不再是默认的test)
应用描述:...运行端口是9090 (不再是8080)

七、开发中常见的「小坑」避坑

  1. yaml配置的缩进问题 :yaml对缩进严格,必须用2个空格,不能用tab,否则配置读取失败;
  2. 默认值的冒号后空格 :yaml中${key:默认值}的冒号后可以有空格 (如${app.mode: test}),properties中不能有空格 (如${app.mode:test},加空格会把空格当成默认值的一部分);
  3. 占位符嵌套 :SpringBoot支持占位符嵌套(如${app.desc:${app.name}默认描述}),但尽量少用,避免配置可读性变差;
  4. @ConfigurationProperties必须有getter/setter :Spring通过反射赋值,没有getter/setter会导致变量值为null

八、总结

  1. SpringBoot配置文件占位符的基础格式${变量名}带默认值的格式${变量名:默认值},冒号是分隔符;
  2. 占位符的核心作用是配置复用、容错兜底、动态配置,是日常开发中提高配置灵活性的必备技巧;
  3. 占位符可以引用配置文件内部变量、系统环境变量、命令行参数,Spring会自动按优先级查找有效值;
  4. 读取带占位符的配置有两种方式:@Value(单个配置)、@ConfigurationProperties(批量配置),根据实际场景选择即可。
相关推荐
Flittly1 天前
【SpringSecurity新手村系列】(3)自定义登录页与表单认证
java·笔记·安全·spring·springboot
Flittly2 天前
【SpringSecurity新手村系列】(2)整合 MyBatis 实现数据库认证
java·安全·spring·springboot·安全架构
极光代码工作室3 天前
基于SpringBoot的在线考试系统
java·springboot·web开发·后端开发
YDS8293 天前
大营销平台 —— 抽奖规则决策树
java·springboot·ddd
码农张34 天前
自定义跨字段校验必填注解
springboot
格鸰爱童话4 天前
向AI学习项目技能(七)
学习·springboot
代码漫谈5 天前
微服务 vs 单体架构:架构选型、实战拆解与决策指南
java·微服务·springboot·springcloud
文慧的科技江湖5 天前
光储充一体化系统落地 PRD 全功能清单 - 慧知开源充电桩平台
java·mysql·开源·springboot·慧知开源充电桩平台·充电重复订单解决方案源码
Flittly5 天前
【SpringAIAlibaba新手村系列】(16)调用百度 MCP 服务
java·笔记·spring·ai·springboot
MegaDataFlowers6 天前
yaml配置注入
springboot