发布于2026-07-23 阅读(0)
扫一扫,手机访问
写代码的时候,最怕什么?最怕改个端口号就得翻遍整个项目,重新打包部署。如果你把端口、数据库账号、第三方密钥这些变量直接写死在代码里——也就是所谓的硬编码——那维护起来可就真成了噩梦。具体来说,会面临三个绕不开的问题:

那配置文件是干嘛用的?说白了,就是把那些经常变动的参数抽离出来,放到一个独立的文件里。程序启动时,自动读取这个文件,所有外部配置都集中管理,一劳永逸。
SpringBoot 内置了两套主流的配置文件:application.properties 和 application.yml(yaml)。它们可以帮你维护端口、数据库、日志、自定义业务参数等几乎所有需要外部化的配置。
配置文件统一放在 src/main/resources 目录下,项目启动后会自动加载。这里有两个默认选项:
application.properties:SpringBoot 创建项目时默认生成,采用经典的键值对格式;application.yml/application.yaml:新式的树形层级格式,可读性更强,也是目前开发中的主流选择。需要留意的是,如果两个文件同时存在,配置会取并集,但 properties 的优先级更高——同名配置会覆盖 yml 中的设置。不过,实际项目中最好统一只用一种格式,同时维护两套配置,很容易把自己绕进去。
格式很简单:key=value,注释用 #,层级关系通过 . 来分隔。
# 修改Tomcat端口 server.port = 9090 # MySQL数据库配置 spring.datasource.url = jdbc:mysql://127.0.0.1:3306/testdb?characterEncoding = utf8&useSSL=false spring.datasource.username = root spring.datasource.password = root # 自定义业务配置 my.test.key=demo123
使用 ${配置key} 就能直接读取参数,适用于那些零散、独立的配置——不过,它只支持单个简单值。
@RestController
@RequestMapping("/prop")
public class PropController {
// 读取properties自定义参数
@Value("${my.test.key}")
private String testKey;
@RequestMapping("/get")
public String getConfig() {
return "读取properties配置:" + testKey;
}
}
当配置层级变多时,重复前缀的问题就暴露出来了:
spring.datasource.url=xxx spring.datasource.username=root spring.datasource.password=root
每一行都要重复写 spring.datasource,层级越深,冗余越严重,看着就头疼。
YAML 的全称是 Yet Another Markup Language(另一种标记语言),它采用树形缩进结构,可读性比 properties 强得多,而且原生支持对象、集合、Map 等复杂数据。
key: value,冒号后面必须加一个英文空格,少了空格,解析直接报错,这一点务必要注意;# 单行注释;{} 简化单层对象/Map,用短横线 - 表示集合元素。拿数据库配置来对比一下:
# application.yml
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/testdb?characterEncoding=utf8&useSSL=false
username: root
password: root
和 properties 比起来,yml 消除了重复前缀,层级关系一目了然。
# 字符串 str: Hello SpringBoot # 布尔值 bool: true # 数字 num: 666 floatNum: 3.14 # null:~代表空值 empty: ~ # 空字符串 emptyStr: ''
string: str1: Hello n Boot # 无引号:n 原样输出,不会换行 str2: 'Hello n Boot' # 单引号:转义所有特殊字符,n 仅作为文本 str3: "Hello n Boot" # 双引号:保留转义字符,n 会自动换行
# 标准缩进写法
person:
id: 1
name: daisy
age: 10
# 行内简写,效果完全一致
person: {id: 1, name: daisy, age: 10}
重点提醒:对象不能用 @Value 读取,必须使用 @ConfigurationProperties 进行批量绑定。
@ConfigurationProperties(prefix = "person")
@Configuration
@Data
public class Person {
private int id ;
private String name;
private int age;
}
db-types:
name:
- mysql
- sqlserver
- db2
List 和数组的配置方式完全一样,既可以用 List 接收,也可以用数组接收。
map-demo:
map:
k1: v1
k2: v2
# 行内简写
map-demo: {map: {k1: v1, k2: v2}}
@Data
@Component
@ConfigurationProperties(prefix = "dbtypes")
public class DBTypes {
private List name;
private Map ball;
}
| 特性 | @Value | @ConfigurationProperties |
|---|---|---|
| 适用场景 | 单个简单参数、零散配置 | 批量绑定一组配置、对象/List/Map |
| 复杂类型 | 不支持对象、集合、Map | 完美支持嵌套对象、List、Map |
| 松散绑定 | 严格匹配key名称 | 支持驼峰、短横线、下划线自动映射 |
不管用 application.properties 还是 application.yml,读取配置的方式都是通过这两个注解来实现的,本质上没有区别。
✅ 优点:
❌ 缺点: 格式要求非常严苛,缩进、空格只要有一处错误,启动就会直接失败。
在 pom.xml 中添加依赖:
cn.hutool hutool-captcha 5.8.22
captcha:
width: 150
height: 50
session:
key: CAPTCHA_SESSION_KEY
date: CAPTCHA_SESSION_DATE
@Data
@Configuration
@ConfigurationProperties(prefix = "captcha")
public class CaptchaProperties {
private Integer width;
private Integer height;
private Session session;
@Data
public static class Session{
private String key;
private String date;
}
}
注意: 普通的内部类不能交给 Spring 管理,因为它必须依托外部类存在。这里改成静态内部类,就不再依赖外部类,能被 Spring 正常管理了。
@RestController
@RequestMapping("/captcha")
public class CaptchaController {
@Autowired
CaptchaProperties captchaProperties;
private final static Long VALID_TIME = 60*1000L;
@RequestMapping("/getCaptcha")
public void getCaptcha(HttpServletResponse response, HttpSession session) throws IOException {
response.setContentType("image/jpeg");
// 理论上由前端处理浏览器缓存问题
response.setHeader("Pragma", "No-cache");
// 生成验证码
ShearCaptcha shearCaptcha = CaptchaUtil.createShearCaptcha(captchaProperties.getWidth(), captchaProperties.getHeight());
String code = shearCaptcha.getCode();
session.setAttribute(captchaProperties.getSession().getKey(), code);
session.setAttribute(captchaProperties.getSession().getDate(), System.currentTimeMillis());
shearCaptcha.write(response.getOutputStream());
response.getOutputStream().close();
}
@RequestMapping("/check")
public boolean check(String captcha, HttpSession session){
// 判空
if(!StringUtils.hasLength(captcha))
return false;
// 验证
Object codeAttr = session.getAttribute(captchaProperties.getSession().getKey());
Object dateAttr = session.getAttribute(captchaProperties.getSession().getDate());
if(codeAttr == null || dateAttr == null)
return false;
String code = codeAttr.toString();
long date = (long) dateAttr;
boolean isValid = System.currentTimeMillis() - date <= VALID_TIME;
return captcha.equalsIgnoreCase(code) && isValid;
}
}
验证码
输入验证码
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8