跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

Spring Boot 配置文件实战:从 Properties 到 YAML 的取舍

Spring Boot 配置文件可选 properties 或 YAML 格式。Properties 键值对简单但冗余严重,YAML 树形结构清晰但要求冒号后必须有空格。读取单值用 @Value,绑定对象和集合推荐 @ConfigurationProperties。以 Hutool 验证码功能为例,演示了将宽高、Session Key 等参数外移至 application.yml,并通过配置属性类注入到控制器,实现业务与配置的解耦。

Qiny01发布于 2026/6/270 浏览
Spring Boot 配置文件实战:从 Properties 到 YAML 的取舍

硬编码让人头疼——环境一换就得改代码。Spring Boot 把数据库连接、端口号这些变数抽到配置文件里,启动时自动加载,省心很多。

配置文件与硬编码对比

Spring Boot 能认三种后缀:.properties、.yml、.yaml。后两者完全等价,只是习惯叫法不同。优先级上,.properties 高于 .yml——如果两个文件里同时写了 server.port,最终生效的是 properties 里的值。所以团队最好统一只用一种格式,免得排查问题时挠头。

Properties 写法与读取

Properties 格式传统,一行一个键值对,= 连接,# 注释。例如:

# 设置项目启动端口
server.port=8080
# 数据库连接配置
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/testdb
spring.datasource.username=root

用 @Value 配合 ${} 就能取到值:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/prop")
@RestController
public class PropertiesController {
    @Value("${spring.datasource.url}")
    private String url;

    @RequestMapping("/read")
    public String readProperties() {
        return "从配置文件中读取 url" + url;
    }
}

运行结果如下:

读取 properties 配置运行结果

但这种写法有个明显的问题——键名越长,重复越多。

properties 配置文件内容

看上图,spring.datasource 这一大串反复出现,读起来很累:

properties 冗余部分

要解决这个冗余,YAML 的树形结构就舒服多了。

YAML 语法与读取

YAML 靠缩进表达层级,键值对中间必须有英文冒号加空格,忘加空格解析直接失败。基本规则如图:

YAML 语法基础

单层级和多层级的缩进区别:

单层级与多层级缩进示例

多层级时每层缩进两个空格,同一级必须对齐。

yml 配置示例:

yml 配置示例

读取方式同样用 @Value:

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/yaml")
@RestController
public class YamlController {
    @Value("${yaml}")
    private String yaml;
    
    @Value("${spring.datasource.username}")
    private String username;
    
    @Value("${spring.datasource.password}")
    private String password;

    @RequestMapping("/read")
    public String read() {
        System.out.println(yaml);
        System.out.println(username);
        System.out.println(password);
        return "success";
    }
}

调用接口后的输出:

YAML 读取运行结果

控制台打印的配置值:

打印配置

字符串引号的坑

YAML 字符串默认可以不加引号,但单引号和双引号的行为不一样:

  • 单引号 '':特殊字符会被转义,比如 \n 就当普通字符输出了。
  • 双引号 "":保留特殊字符原意,\n 就是换行。

引号差异示例1

引号差异示例2

对象、集合和 Map 的绑定
配置对象
student:
  id: 1
  name: Java
  age: 18

用 @ConfigurationProperties 映射到 bean:

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@ConfigurationProperties(prefix = "student")
@Component
public class Student {
    private Integer id;
    private String name;
    private Integer age;
}

绑定后的打印结果:

对象配置打印结果

配置集合
dbtypes:
  name:
    - mysql
    - sqlserver
    - db2
  map:
    k1: kk1
    k2: kk2
    k3: kk3

绑定类:

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

@Data
@ConfigurationProperties(prefix = "dbtypes")
@Component
public class DbTypeConfig {
    private List<String> name;
    private Map<String, String> map;
}

运行效果:

集合配置打印结果

综合练习:验证码功能

下面通过一个验证码接口演示配置到底怎么用。需求很简单:后端生成图形验证码,存入 session,校验时判断一致性以及是否超时(一分钟)。把宽、高、Session Key 这些容易变的参数都放到配置文件里,避免硬编码。

验证码需求概述

Hutool 工具说明

验证码处理流程

配置文件
spring:
  application:
    name: spring-captcha-demo
  captcha:
    width: 100
    height: 40
  session:
    code: SESSION_CODE_KEY
    date: SESSION_DATE_KEY
接口实现
import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;

@RestController
@RequestMapping("/captcha")
public class CaptchaController {
    @Autowired
    private CaptchaProperties captchaProperties;

    private static long VALID_MILLIS_TIME = 60 * 1000;

    @RequestMapping("/getCaptcha")
    public void genCaptcha(HttpServletRequest request, HttpServletResponse response) {
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(captchaProperties.getWidth(), captchaProperties.getHeight());
        String code = lineCaptcha.getCode();
        System.out.println(code);
        try {
            response.setContentType("image/jpeg");
            response.setHeader("Pragma", "No-cache");
            lineCaptcha.write(response.getOutputStream());
            HttpSession session = request.getSession();
            session.setAttribute(captchaProperties.getSession().getCode(), code);
            session.setAttribute(captchaProperties.getSession().getDate(), System.currentTimeMillis());
            response.getOutputStream().close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @RequestMapping("/check")
    public Boolean checkCaptcha(String captcha, HttpSession session) {
        if (!StringUtils.hasLength(captcha)) {
            return false;
        }
        Object codeObj = session.getAttribute(captchaProperties.getSession().getCode());
        if (codeObj == null) return false;
        String code = codeObj.toString();
        long timestamp = (long) session.getAttribute(captchaProperties.getSession().getDate());
        if (captcha.equalsIgnoreCase(code) && (System.currentTimeMillis() - timestamp < VALID_MILLIS_TIME)) {
            return true;
        }
        return false;
    }
}

前端页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>验证码</title>
    <style>
        #inputCaptcha { height: 30px; vertical-align: middle; }
        #verificationCodeImg { vertical-align: middle; }
        #checkCaptcha { height: 40px; width: 100px; }
    </style>
</head>
<body>
    <h1>输入验证码</h1>
    <div id="confirm">
        <input type="text" name="inputCaptcha" id="inputCaptcha">
        <img id="verificationCodeImg" src="/captcha/getCaptcha" style="cursor: pointer;" title="看不清?换一张"/>
        <input type="button" value="提交" id="checkCaptcha">
    </div>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
    <script>
        $("#verificationCodeImg").click(function(){
            $(this).hide().attr('src','/captcha/getCaptcha?dt='+new Date().getTime()).fadeIn();
        });
        $("#checkCaptcha").click(function(){
            $.ajax({
                url:'/captcha/check',
                type:'post',
                data:{ captcha:$('#inputCaptcha').val()},
                success:function(result){
                    if(result){
                        location.href ='success.html';
                    }else{
                        alert("验证码错误!");
                    }
                }
            });
        });
    </script>
</body>
</html>

最终运行效果:

验证码运行效果1

验证码运行效果2

验证码获取接口

Properties 上手快,但项目一大键名就臃肿;YAML 结构好读,适合复杂配置,只是需要注意空格。取值时,单个参数用 @Value,要是一组相关配置就绑到 @ConfigurationProperties,代码干净很多。

参考链接:

  • Spring Boot 官方外部配置文档
  • Hutool 工具地址

目录

  1. Properties 写法与读取
  2. 设置项目启动端口
  3. 数据库连接配置
  4. YAML 语法与读取
  5. 字符串引号的坑
  6. 对象、集合和 Map 的绑定
  7. 配置对象
  8. 配置集合
  9. 综合练习:验证码功能
  10. 配置文件
  11. 接口实现
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 法奥机器人 ROS2 环境搭建
  • 云原生算力调度:基于 Kubernetes 的智能资源分配
  • C++ 类的 6 个默认成员函数与运算符重载
  • VSCode 远程连接 SSH 服务器教程
  • RK3588 MIPI 采集与硬件编码推流实战:OpenCV 处理及 WebRTC 低延迟方案
  • 图寻路算法详解:基于深度优先搜索 (DFS) 实现
  • 网络安全学习指南:核心知识与路径
  • ChatGPT 插件生态爆发:自动写书玩法与插件知识库构建方法
  • Android 使用 ZXing 库实现二维码扫描与生成
  • 算法:长度最小的子数组(滑动窗口解法)
  • 接入第三方 OpenAI 兼容模型到 GitHub Copilot
  • AI 产品经理入门:能力模型与核心概念梳理
  • 预训练语言模型与 BERT 实战应用
  • LLM 评估框架详解:Arthur Bench 实践指南
  • GitHub Copilot 在 VS Code 中的 AI 代理开发指南
  • CentOS 7 + Docker 部署 KaiwuDB 社区版 3.1.0 全流程及跨模查询实测
  • Linux 网络基础:局域网与跨网段通信原理
  • Web 项目 UI 自动化测试实战:从零搭建博客系统框架
  • Ubuntu 22.04 配置 MID360 激光雷达
  • 2025 机构开发栈:14 款 Web 模板与技术选型深度评测
  • 相关免费在线工具

    • Keycode 信息

      查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

    • Escape 与 Native 编解码

      JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

    • JavaScript / HTML 格式化

      使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

    • JavaScript 压缩与混淆

      Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

    • Base64 字符串编码/解码

      将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

    • Base64 文件转换器

      将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online