SpringBoot 配置文件详解:Properties 与 YML 格式对比
SpringBoot 支持 properties 和 yml/yaml 两种配置文件格式。properties 采用键值对形式,yml 采用缩进结构,后者可读性更高且支持复杂数据类型。配置项可通过@Value 注解直接注入,对象或集合则推荐使用@ConfigurationProperties 绑定。详细讲解了两者的语法差异、读取方式及优先级规则,并通过验证码案例演示了结合 Hutool 工具包的实际应用。

SpringBoot 支持 properties 和 yml/yaml 两种配置文件格式。properties 采用键值对形式,yml 采用缩进结构,后者可读性更高且支持复杂数据类型。配置项可通过@Value 注解直接注入,对象或集合则推荐使用@ConfigurationProperties 绑定。详细讲解了两者的语法差异、读取方式及优先级规则,并通过验证码案例演示了结合 Hutool 工具包的实际应用。

计算机上有数以千计的配置文件,我们使用的绝大多数软件,比如浏览器、微信、Idea,甚至电脑、手机,都离不开配置文件。配置文件主要是为了解决硬编码带来的问题,把可能会发生改变的信息,放在一个集中的地方,当我们启动某个程序时,应用程序从配置文件中读取数据,并加载运行。
硬编码是将数据直接嵌入到程序或其他可执行对象的源代码中,也就是我们常说的'代码写死'。
使用配置文件,可以使程序完成用户和应用程序的交互,或者应用程序与其他应用程序的交互。
SpringBoot 支持并定义了配置文件的格式,也在另一个层面达到了规范其他框架集成到 SpringBoot 的目的。
很多项目或者框架的配置信息也放在配置文件中,比如: • 项目的启动端口:SpringBoot 内置了 Tomcat 服务器,默认端口号是 8080。 • 数据库的连接信息(包含用户名和密码的设置):对 JDBC 进行了更深层次的封装,让用户通过简单几行代码就可完成数据库的访问。 • 第三方系统的调用密钥等信息。 • 用于发现和定位问题的普通日志和异常日志等。

修改 application.properties 文件:
server.port=9090
启动程序,观察日志:

显示 Tomcat 启动端口号为 9090。
Spring Boot 配置文件有以下三种: Ⅰ application.properties Ⅱ application.yml Ⅲ application.yaml
yml 为 yaml 的简写,实际开发中出现频率最高。yaml 和 yml 的使用方式一样,文章中只介绍 yml 文件的使用。
当应用程序启动时,Spring Boot 会自动从 classpath 路径找到并加载 application.properties 和 application.yaml 或者 application.yml 文件。

如上图所示,properties 和 yml 可以并存于一个项目中,当 .properties 和 .yml 并存时,两个配置都会加载。如果配置文件内容有冲突,则以 .properties 为主,也就是 .properties 优先级更高。需要注意的是虽然 .properties 可以和 .yml 共存,但是实际开发当中,我们通常会采取一种统一的配置文件格式,这样方便后续的维护,降低出故障的概率。
properties 配置文件是最早期的配置文件格式,也是创建 SpringBoot 项目默认的配置文件。
properties 是以键值的形式配置的,key 和 value 之间是以"="连接的,如:
# 配置项目端口号
server.port=9090
# 配置数据库连接信息
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/testdb?characterEncoding=utf8&useSSL=false
spring.datasource.username=handsome
spring.datasource.password=boy
想了解 Spring Boot 配置文件更多内容和细节:Spring Boot 配置文件官网
如果在项目中,想要主动的读取配置文件中的内容,可以使用 @Value 注解来实现。 @Value 注解使用 "${}" 的格式读取,如下代码所示:
properties 配置如下:
server.port=9090
mykey=aa
创建一个新的类 ReadymlController:
@RequestMapping("/yml")
@RestController
public class ReadymlController {
@Value("${mykey}")
private String key;
@RequestMapping("/readyml")
public String readYml() {
return "从 yml 中获取配置文件:" + key;
}
}
运行程序,并在浏览器访问 http://127.0.0.1:9090/yml/readyml,有如下结果说明获取成功。

properties 配置文件中会有很多的冗余的信息,比如:

想要解决这个问题,就可以使用 yml 配置文件的格式化。
yml 全称 Yet Another Markup Language,翻译成中文就是'另一种标记语言'。
yml 是树形结构的配置文件,它的基础语法是"key: value"。 key 和 value 之间使用英文冒号加空格的方式组成,空格不可省略。

使用 yml 连接数据库:
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/dbname?characterEncoding=utf8&useSSL=false
username: root
password: root
可以发现不用像 properties 那样重复去写 spring 和 datasource。
# 字符串
string.value: hello
# 布尔值,true 或 false
boolean.value: true
boolean.value1: false
# 整数
int.value: 520
# 浮点数
float.value: 13.14
# Null, ~代表 null
null.value: ~
# 空字符串
empty.value: ''
# 直接后面什么都不加也可以,但是这种方式不直观
empty.value1:
yml 读取配置的方式和 properties 相同,使用 @Value 注解即可,实现代码如下:
yml 配置:
server:
port: 9090
str:
value: hello
ReadymlController 文件代码:
@Value("${mykey}")
private String key;
@Value("${str.value}")
private String string;
@RequestMapping("/readymlstr")
public String readYmlstr() {
return "从 yml 中获取配置文件:" + string;
}
@RequestMapping("/readyml")
public String readYml() {
return "从 yml 中获取配置文件:" + key;
}
访问 http://127.0.0.1:9090/yml/readymlstr,运行结果:

字符串默认不用加上单引号或者双引号,如果加英文的单双引号可以表示特殊的含义。 在 application.yml 中配置如下信息:
string:
str1: Hello \n SpringBoot.
str2: 'Hello \n SpringBoot.'
str3: "Hello \n Spring Boot."
ReadymlController 文件代码:
@Value("${string.str1}")
private String str1;
@Value("${string.str2}")
private String str2;
@Value("${string.str3}")
private String str3;
@RequestMapping("/readyml4")
public String readYml4() {
System.out.println(str1);
System.out.println(str2);
System.out.println(str3);
return "从 yml 中获取配置文件";
}
以上程序的执行结果如下图所示:

从上述结果可以看出:
字符串默认不用加上单引号或者双引号。 单引号会转义特殊字符,使其失去特殊功能,始终是一个普通的字符串。 双引号不会转义字符串里面的特殊字符,特殊字符会表示本身的含义。 \n 本意表示的是换行,使用单引号会转义,就是说,\n 不再表示换行了,而是表示一个普通的字符串。用双引号不会转义,表示\n 表示的是它本身的含义,就是换行。
yml 中配置对象:
student:
id: 1
name: Java
age: 18
这个时候就不能用@Value 来读取配置中的对象了,此时要使用另一个注解@ConfigurationProperties 来读取,在 Student 文件中:
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 配置对象
*/
@ConfigurationProperties(prefix = "student") // 从配置文件中获取默认值
@Component // 交给 spring 管理
@Data
public class Student {
// id: 1
// name: Java
// age: 18
private Integer id;
private String name;
private Integer age;
}
调用类的实现如下:
@RequestMapping("/yml")
@RestController
public class ReadymlController {
@Autowired
private Student student;
@RequestMapping("/readStudent")
public String readStudent() {
return "从 yml 中获取配置文件 Student: " + student;
}
}
运行结果如下所示:

配置文件也可以配置 list 集合,如下所示:
dbtypes:
name:
- mysql
- sqlserver
- db2
集合的读取和对象一样,也是使用@ConfigurationProperties 来读取的。
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 配置集合
*/
@ConfigurationProperties("dbtypes")
@Component
@Data
public class DbType {
private List<String> name;
}
访问集合的实现如下:
@RequestMapping("/yml")
@RestController
public class ReadymlController {
@Autowired
private DbType dbType;
@RequestMapping("/readDbtype")
public String readDbtype() {
return "从 yml 中获取配置文件 readDbtype: " + dbType;
}
}
配置文件也可以配置 map:
maptypes:
map:
k1: 1
k2: 2
k3: 3
Map 的读取和对象一样,也是使用@ConfigurationProperties 来读取的。
import java.util.Map;
@ConfigurationProperties("maptypes")
@Component
@Data
public class MapType {
private Map<String, String> map;
}
打印类实现如下:
@RequestMapping("/yml")
@RestController
public class ReadymlController {
@Autowired
private MapType mapType;
@RequestMapping("/readMaptype")
public String readMaptype() {
return "从 yml 中获取配置文件 readMaptype: " + mapType;
}
}
优点:
缺点:
随着安全性的要求越来越高,目前项目中很多都使用了验证码,验证码的形式也是多种多样,更复杂的图形验证码和行为验证码已经成为了更流行的趋势。
验证码的实现方式很多,网上也有比较多的插件或者工具包可以使用,本文选择使用 Hutool 工具包来实现。
详细见链接:Hutool
原理 验证码可以客户端生成,也可以服务器生成。对于普通的字符验证码,后端通常分两部分。 一是生成验证码内容,根据验证码内容干扰项等,生成图片,返回给客户端。 二是把验证码内容存储起来,校验时取出来进行对比。Hutool 把验证码存储在 Session 里。
使用前需引入 Hutool 依赖。
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-captcha</artifactId>
<version>5.8.16</version>
</dependency>
界面如下图所示:

创建项目 (captcha),引入 SpringMVC 的依赖包,把前端页面放在项目中。
需求分析 后端需要提供两个服务
接口定义:
生成验证码 请求:captcha / get 参数:session 存储图片上的答案,方便比较。 返回值:无。
校验验证码是否正确。 请求:captcha / check 参数:inputCode, session 返回值:true 或 false。
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-captcha</artifactId>
<version>5.8.16</version>
</dependency>
captcha:
width: 200
height: 100
session:
key: captcha_session_key
date: captcha_session_date
@RequestMapping("/captcha")
@RestController
public class CaptchaController {
private final static long session_valid_timeout = 60 * 1000;
@Autowired
private CaptchaProperties captchaProperties;
@RequestMapping("/get")
public void getCaptcha(HttpSession session, HttpServletResponse response) {
// 响应中的所有数据都可以去 response 中拿
LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(captchaProperties.getWidth(), captchaProperties.getHeight());
// 抓包发现该请求没有 ContentType,但是 Spring 默认会返回 ContentType
response.setContentType("image/jpeg");
// 禁止缓存
response.setHeader("Progma", "No-cache");
// 图形验证码写出,可以写出到文件,也可以写出到流
try {
lineCaptcha.write(response.getOutputStream());
String code = lineCaptcha.getCode();
// 拿到验证码答案
// 存储 sesion
session.setAttribute(captchaProperties.getSession().getKey(), code);
session.setAttribute(captchaProperties.getSession().getDate(), new Date());
// 记录设置 session 时的时间
response.getOutputStream().close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
Boolean {
(!StringUtils.hasLength(inputCode)) {
;
}
(String) session.getAttribute(captchaProperties.getSession().getKey());
(Date) session.getAttribute(captchaProperties.getSession().getDate());
(saveCode.equalsIgnoreCase(inputCode)) {
(saveDate != && System.currentTimeMillis() - saveDate.getTime() < session_valid_timeout) {
;
}
}
;
}
}
在 index.html 中,补充 ajax 代码,点击提交按钮,发送请求去服务端进行校验。
$("#checkCaptcha").click(function () {
$.ajax({
url: "captcha/check",
type: "post",
data: {
inputCode: $("#inputCaptcha").val()
},
success: function (result) {
if (result == true) {
location.href = "success.html";
} else {
alert("验证码错误或者过期");
}
}
});
});
通过 URL http://127.0.0.1:8080/index.html 访问服务

输入验证码


微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online