在基于 Spring Boot 的应用开发中,配置文件扮演着至关重要的角色,它是连接应用代码与运行时环境的桥梁。application.yml 和 application.properties 是两种最主流的配置格式。开发者不仅需要了解它们的语法差异,更应掌握如何利用它们进行多环境配置管理以及如何保障敏感配置信息的安全。
一、YAML 与 Properties:语法差异与选型指南
application.properties 采用传统的键值对语法,而 application.yml 则基于 YAML 语言,使用缩进来表示层级结构。两者在功能上等效,但在语法和适用场景上各有特点。
1. 基础语法对比
(1) application.properties:键值对格式
其语法为 key=value,通过点号.来表达层级关系,且大小写敏感。
# 应用基础配置
spring.application.name=boot-config-demo
server.port=8080
server.servlet.context-path=/api
# 数据库配置
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 集合配置示例
spring.profiles.include=dev,test
spring.redis.cluster.nodes[0]=127.0.0.1:6379
spring.redis.cluster.nodes[1]=127.0.0.1:6380
(2) application.yml:层级缩进格式
其语法为 key: value(冒号后必须有空格),使用缩进(推荐2个空格,禁止使用Tab)来体现层级,天生支持复杂数据结构。
# 应用基础配置
spring:
application:
name: boot-config-demo
server:
port: 8080
servlet:
context-path: /api
# 数据库配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/test
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
# 集合配置
spring:
profiles:
include: [dev, test]
redis:
cluster:
nodes:
- 127.0.0.1:6379
- 127.0.0.1:6380
# 多行字符串(|保留换行,>折叠换行)
app:
desc: |
这是一个多行字符串
换行符会被保留
summary: >
这是折叠换行的字符串,
换行符会被替换为空格。
2. 核心特性对比
| 特性 |
application.properties |
application.yml |
| 语法风格 |
扁平键值对,层级深时显冗长 |
层级缩进,结构直观清晰 |
| 可读性 |
简单直接,易于理解 |
复杂配置下结构更清晰,但对格式敏感 |
| 数据类型 |
仅支持字符串,需类型转换 |
原生支持字符串、数字、布尔、集合、对象 |
| 多行文本 |
不支持,需转义,较为繁琐 |
原生支持,语法简洁 |
| 加载优先级 |
同级目录下,优先级高于 .yml 文件 |
同级目录下,优先级低于 .properties 文件 |
3. 格式选型建议
- 选择 Properties:当项目配置较为简单、团队成员更熟悉传统格式,或需要维护遗留的 Spring 项目时。
- 选择 YAML:当项目配置复杂(例如微服务架构)、需要定义嵌套对象或列表,或追求配置文件更高的简洁性与可读性时。
- 重要原则:一个项目中应尽量避免同时使用两种格式,以防止配置冲突和混淆。
二、多环境配置管理:实现开发、测试与生产的平滑切换
在实际项目研发中,通常需要区分开发(dev)、测试(test)与生产(prod)等不同环境。Spring Boot 提供了优雅的多环境配置支持。
1. 配置文件命名规范
多环境配置需遵循 application-{profile}.yml 或 application-{profile}.properties 的命名规则,{profile} 为环境标识。
建议的项目配置文件结构:
application.yml:主配置文件,存放所有环境的通用配置。
application-dev.yml:开发环境专属配置。
application-test.yml:测试环境专属配置。
application-prod.yml:生产环境专属配置。
2. 配置分离原则
通用配置置于主文件,环境差异配置置于环境专属文件。启动时,环境专属配置会覆盖主配置中的相同属性。
示例:
主配置文件 (application.yml):
spring:
application:
name: boot-config-demo
profiles:
active: dev # 默认激活开发环境
开发环境配置 (application-dev.yml):
server:
port: 8080
spring:
datasource:
url: jdbc:mysql://localhost:3306/dev_db
logging:
level:
root: DEBUG
生产环境配置 (application-prod.yml):
server:
port: 80
spring:
datasource:
url: jdbc:mysql://192.168.1.100:3306/prod_db
password: Prod@123456 # 生产环境使用强密码
logging:
level:
root: WARN
3. 激活环境的三种方式
- 主配置文件指定(常用于开发):
spring:
profiles:
active: prod
- 命令行参数指定(常用于生产部署,优先级最高):
java -jar your-app.jar --spring.profiles.active=prod
- 系统环境变量指定(适用于 Docker 等容器化部署):
export SPRING_PROFILES_ACTIVE=prod
java -jar your-app.jar
三、配置信息安全:使用Jasypt进行敏感数据加密
明文存储数据库密码、API密钥等敏感信息存在严重安全风险。集成 Jasypt 库可以为配置项提供加密解密能力。
1. 实现原理
- 加密:将明文敏感信息转换为密文。
- 存储:将密文(包裹在
ENC() 内)写入配置文件。
- 解密:应用启动时,Jasypt 自动解密配置。
- 密钥管理:解密的密钥通过外部方式(命令行、环境变量)传入,不写死在配置文件中。
2. 集成与加密步骤
(1) 添加依赖
在 pom.xml 中引入 starter:
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
(2) 生成加密密文
编写一个简单的工具类生成密文:
import org.jasypt.util.text.BasicTextEncryptor;
public class JasyptUtil {
public static void main(String[] args) {
BasicTextEncryptor encryptor = new BasicTextEncryptor();
// 设置加密密钥(此密钥需妥善保管)
encryptor.setPassword("MySecretKey@2024");
String plainText = "Prod@123456";
String cipherText = encryptor.encrypt(plainText);
System.out.println("密文: " + cipherText);
System.out.println("配置文件中的写法: ENC(" + cipherText + ")");
}
}
(3) 在配置文件中使用密文
在 application-prod.yml 中,用 ENC(密文) 替换明文密码:
spring:
datasource:
password: ENC(AQB1c2VyMTIzQEAxMjM0NTY3ODkw) # 加密后的密码
(4) 启动时传入密钥
通过命令行参数传入解密密钥:
java -jar your-app.jar --jasypt.encryptor.password=MySecretKey@2024
3. 安全最佳实践
- 密钥隔离:加解密密钥必须通过环境变量或命令行传入,禁止硬编码。
- 最小化加密:仅对密码、密钥等敏感信息加密。
- 强密钥策略:使用足够复杂且定期更换的密钥。
- 文件权限控制:确保服务器上的配置文件访问权限最小化。
四、配置使用进阶技巧
1. 配置参数引用
使用 ${...} 语法引用已定义的配置,避免重复。
app:
domain: example.com
api-path: /api/v1
server:
servlet:
context-path: ${app.api-path}
2. 占位符默认值
使用 :默认值 为可能未定义的配置项提供后备值,增强鲁棒性。
server:
port: ${SERVER_PORT:8080} # 优先使用环境变量SERVER_PORT,不存在则使用8080
3. 外部配置加载优先级
Spring Boot 按以下优先级从高到低加载配置(高优先级覆盖低优先级):
- 命令行参数
- 系统环境变量
- 项目根目录下
/config 文件夹中的配置文件
- 项目根目录下的配置文件
- classpath 下
/config 包中的配置文件
- classpath 根目录下的配置文件
五、总结
- 格式选择:根据配置复杂度在 YAML 与 Properties 间做出合适选择,并保持统一。
- 环境管理:遵循“主配置通用,环境配置差异化”原则,利用
spring.profiles.active 灵活切换。
- 配置安全:对敏感信息必须使用类似 Jasypt 的工具进行加密,密钥通过外部渠道管理。
- 高效实践:善用配置引用和默认值提升配置的复用性与健壮性,并严格控制配置文件访问权限。
规范的配置文件管理是保障 Spring Boot 应用可维护性、安全性与部署灵活性的基石。