咱们拆了 Spring Boot 的 3 个 “黑科技”,但实际开发中还有个高频痛点 —— 配置管理。新手常把配置写得乱七八糟:开发环境和生产环境的数据库密码混在一起、想改个参数要翻半天配置文件、数据库密码明文存着怕泄露……
这就像奶茶店的 “配方手册” 没管好:堂食和外卖的糖量配方写在一张纸上、想查 “珍珠煮多久” 要翻遍整本手册、配方上的核心原料比例随便让人看 —— 乱、慢、不安全。
今天咱们就讲 Spring Boot 的 “配置管理实战”,把配置当成 “奶茶配方” 来管:多环境配置(不同场景用不同配方)、灵活读取配置(快速查配方)、敏感配置加密(核心配方锁起来),全程实战 + 避坑,新手也能把配置管得明明白白。
一、多环境配置:给不同场景 “配不同配方”
开发时用本地数据库、测试时用测试服务器、上线时用生产数据库 —— 如果把所有配置写在一个文件里,切换环境时要手动改,容易出错(比如把生产密码改成开发的)。
Spring Boot 的多环境配置,就像奶茶店给 “堂食、外卖、批发” 做不同配方:堂食糖多、外卖打包加冰、批发量大优惠,用不同的配方页(配置文件),切换时只需要 “选配方”(激活环境)。
1. 多环境配置的 3 种写法(新手选第一种)
写法 1:多文件配置(最直观,推荐新手)
在下建 3 个配置文件,命名规则是
src/main/resources:
application-{环境名}.yml
:开发环境(自己电脑用)
application-dev.yml:测试环境(测试服务器用)
application-test.yml:生产环境(线上服务器用)
application-prod.yml
再保留一个(主配置文件),用来 “激活环境”(选哪个配方),结构如下:
application.yml
plaintext
src/main/resources/
├─ application.yml # 主配置(激活环境、公共配置)
├─ application-dev.yml # 开发环境配置
├─ application-test.yml # 测试环境配置
└─ application-prod.yml # 生产环境配置
写法 2:单文件多文档(用 — 分隔,适合配置少的场景)
如果配置不多,可把所有环境写在一个里,用
application.yml分隔不同环境:
---
yaml
# 主配置:激活开发环境
spring:
profiles:
active: dev
# 开发环境(用---分隔)
---
spring:
profiles: dev
datasource:
url: jdbc:mysql://localhost:3306/dev_db
username: root
password: 123456
# 生产环境(用---分隔)
---
spring:
profiles: prod
datasource:
url: jdbc:mysql://192.168.1.200:3306/prod_db
username: prod_user
password: xxxxxxxx
写法 3:命令行激活环境(部署时临时切换)
不用改配置文件,启动项目时用命令行指定环境,适合部署时临时切换:
bash
# 启动开发环境(命令行参数--spring.profiles.active=dev)
java -jar spring-boot-demo.jar --spring.profiles.active=dev
# 启动生产环境
java -jar spring-boot-demo.jar --spring.profiles.active=prod
2. 实战:多环境配置落地(开发→生产无缝切换)
咱们以 “数据库配置” 为例,手把手实现多环境配置:
建 3 个环境配置文件:
(开发环境,本地数据库):
application-dev.yml
yaml
spring:
datasource:
url: jdbc:mysql://localhost:3306/dev_book_db?useUnicode=true&characterEncoding=utf8
username: root
password: 123456 # 本地数据库密码
server:
port: 8080 # 开发环境用8080端口
(生产环境,服务器数据库):
application-prod.yml
yaml
spring:
datasource:
url: jdbc:mysql://192.168.1.200:3306/prod_book_db?useUnicode=true&characterEncoding=utf8
username: prod_user
password: Prod@123456 # 生产数据库密码(复杂点)
server:
port: 80 # 生产环境用80端口(默认http端口)
主配置文件(激活环境 + 公共配置):
application.yml
yaml
# 公共配置:所有环境都能用(比如Redis地址、缓存过期时间)
spring:
redis:
host: localhost
port: 6379
profiles:
active: dev # 默认激活开发环境,上线时改成prod或用命令行切换
# 公共缓存配置
book:
cache:
expire: 30 # 缓存30分钟
测试切换效果:
启动项目,默认用开发环境(8080 端口,连本地数据库);想切换到生产环境,要么把改成
active,要么用命令行启动:
prod,项目会自动用 80 端口,连生产数据库。
java -jar spring-boot-demo.jar --spring.profiles.active=prod
3. 避坑:多环境配置的 3 个常见错误
错误 1:环境名写错(比如写成
application-prod.yml)—— 激活时 Spring 找不到对应环境,会用默认配置,解决:严格按
application-product.yml命名,环境名和激活参数一致;错误 2:公共配置重复写(比如 3 个环境都写了 Redis 地址)—— 冗余且难维护,解决:公共配置放
application-{环境名}.yml,环境特有配置(数据库、端口)放对应环境文件;错误 3:激活多个环境冲突(比如
application.yml)——Spring 只会加载最后一个环境,解决:一次只激活一个环境。
active: dev,prod
二、配置读取:3 种方式快速拿 “配方参数”
配置写好了,怎么在代码里读取?比如想拿这个参数,或数据库地址,Spring Boot 提供了 3 种常用方式,像奶茶店查配方的 3 种方法:翻手册(@Value)、查分类目录(@ConfigurationProperties)、问店长(Environment)。
book.cache.expire=30
1. 方式 1:@Value 注解(快速查单个配置,像翻手册找单个配方)
适合读取单个简单配置(字符串、数字、布尔值),直接在变量上加,不用写多余代码。
@Value("${配置键}")
实战:用 @Value 读配置
java
运行
package com.example.springbootdemo.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ConfigReadController {
// 读取单个简单配置:缓存过期时间(book.cache.expire)
@Value("${book.cache.expire}")
private Integer cacheExpire;
// 读取数据库URL(环境特有配置)
@Value("${spring.datasource.url}")
private String dbUrl;
// 读取配置,带默认值(如果配置里没写book.name,就用默认值“Java实战”)
@Value("${book.name:Java实战}")
private String bookName;
@GetMapping("/readConfig1")
public String readConfig1() {
return "缓存过期时间:" + cacheExpire + "分钟,数据库地址:" + dbUrl + ",图书名称:" + bookName;
}
}
启动项目,访问,就能看到读取到的配置值,简单直接。
http://localhost:8080/readConfig1
2. 方式 2:@ConfigurationProperties(批量读配置,像查分类目录)
如果要读取一组相关配置(比如、
book.cache.expire),用
book.cache.prefix要写多个注解,麻烦。
@Value能批量绑定配置到实体类,像奶茶店查 “珍珠相关配方”(煮制时间、用量、温度),直接翻 “珍珠分类目录”,不用一个个找。
@ConfigurationProperties
实战:用 @ConfigurationProperties 批量读配置
先在里加一组相关配置:
application.yml
yaml
book:
cache:
expire: 30 # 缓存过期时间
prefix: "book_" # 缓存key前缀
enabled: true # 是否启用缓存
新建配置实体类,批量绑定:
java
运行
package com.example.springbootdemo.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
// @Component:让Spring扫描到这个类
@Component
// @ConfigurationProperties(prefix = "book.cache"):绑定前缀为book.cache的所有配置
@ConfigurationProperties(prefix = "book.cache")
@Data // Lombok自动生成get/set方法
public class BookCacheProperties {
// 配置键:book.cache.expire → 变量名expire(驼峰命名自动匹配)
private Integer expire;
// 配置键:book.cache.prefix → 变量名prefix
private String prefix;
// 配置键:book.cache.enabled → 变量名enabled
private Boolean enabled;
}
在 Controller 里注入使用:
java
运行
@RestController
public class ConfigReadController {
// 注入批量配置实体类
private final BookCacheProperties bookCacheProperties;
// 构造注入(比@Autowired更规范)
public ConfigReadController(BookCacheProperties bookCacheProperties) {
this.bookCacheProperties = bookCacheProperties;
}
@GetMapping("/readConfig2")
public String readConfig2() {
return "缓存前缀:" + bookCacheProperties.getPrefix() +
",过期时间:" + bookCacheProperties.getExpire() +
"分钟,是否启用:" + bookCacheProperties.getEnabled();
}
}
访问,就能批量读取到配置,适合一组相关配置的场景。
http://localhost:8080/readConfig2
3. 方式 3:Environment(动态读配置,像问店长要配方)
如果配置键是动态的(比如根据用户输入的键读取对应配置),或想判断配置是否存在,用接口,像奶茶店遇到不确定的配方,直接问店长 “有没有这个配方”“配方值是多少”。
Environment
实战:用 Environment 读配置
java
运行
@RestController
public class ConfigReadController {
// 注入Environment对象
private final Environment environment;
public ConfigReadController(Environment environment) {
this.environment = environment;
}
@GetMapping("/readConfig3/{key}")
public String readConfig3(@PathVariable String key) {
// 读取指定键的配置
String value = environment.getProperty(key);
if (value == null) {
return "配置键" + key + "不存在!";
}
// 判断配置是否存在
boolean hasKey = environment.containsProperty(key);
return "配置键" + key + "的值:" + value + ",是否存在:" + hasKey;
}
}
访问,会返回 “配置键 book.cache.expire 的值:30,是否存在:true”;访问
http://localhost:8080/readConfig3/book.cache.expire,会提示配置不存在,灵活度很高。
http://localhost:8080/readConfig3/abc
4. 3 种读取方式对比(选对才高效)
| 读取方式 | 核心优势 | 适用场景 | 新手推荐度 |
|---|---|---|---|
|
简单直接,一行代码搞定 | 读取单个简单配置(如端口、单个参数) | ⭐⭐⭐⭐⭐ |
|
批量绑定,支持校验,类型安全 | 读取一组相关配置(如缓存配置、数据库配置) | ⭐⭐⭐⭐ |
|
动态读取,支持判断配置是否存在 | 配置键动态生成、需要判断配置存在性 | ⭐⭐⭐ |
三、敏感配置加密:给核心配方 “上锁”(防泄露)
数据库密码、Redis 密码、第三方 API 密钥这些敏感配置,明文存在配置文件里太危险 —— 万一配置文件被泄露,核心信息就没了,像奶茶店的核心配方被竞争对手偷走。
Spring Boot 用插件就能实现敏感配置加密,把明文变成密文,像给配方上把锁,只有奶茶店内部知道钥匙(加密密钥),别人拿到配方也没用。
jasypt
1. 实战:敏感配置加密(数据库密码加密)
步骤 1:加 jasypt 依赖(给配方锁 “装零件”)
xml
<!-- 敏感配置加密依赖 -->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.4</version>
</dependency>
步骤 2:生成加密后的密文(给配方 “上锁”)
写一个简单的测试类,生成数据库密码的密文(也可以用命令行生成):
java
运行
package com.example.springbootdemo;
import org.jasypt.encryption.StringEncryptor;
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
public class JasyptTest {
public static void main(String[] args) {
// 加密密钥(生产环境要存在环境变量,别写配置文件)
String encryptKey = "myBookKey123"; // 钥匙
String plainText = "123456"; // 要加密的明文(数据库密码)
// 配置加密器
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword(encryptKey); // 密钥
config.setAlgorithm("PBEWithMD5AndDES"); // 加密算法(默认)
config.setKeyObtentionIterations("1000");
config.setPoolSize("1");
encryptor.setConfig(config);
// 加密明文→密文
String cipherText = encryptor.encrypt(plainText);
System.out.println("加密后的密文:" + cipherText);
// 解密密文→明文(验证)
String decryptText = encryptor.decrypt(cipherText);
System.out.println("解密后的明文:" + decryptText);
}
}
运行后,控制台会输出加密后的密文(比如),复制这个密文。
ENC(abc123xyz...)
步骤 3:配置文件用密文(用加密配方)
在里,把数据库密码换成密文,格式是
application-dev.yml:
ENC(密文)
yaml
spring:
datasource:
url: jdbc:mysql://localhost:3306/dev_book_db?useUnicode=true&characterEncoding=utf8
username: root
password: ENC(abc123xyz...) # 加密后的密文
jasypt:
encryptor:
password: ${JASYPT_ENCRYPT_KEY} # 密钥从环境变量获取(生产环境用)
步骤 4:启动项目(用钥匙 “解锁” 配方)
开发环境:在 IDEA 里设置环境变量(和加密时的密钥一致),启动项目,Spring Boot 会自动解密密文,正常连接数据库;生产环境:把密钥存到服务器环境变量(Linux:
JASYPT_ENCRYPT_KEY=myBookKey123;Windows:
export JASYPT_ENCRYPT_KEY=myBookKey123),启动项目即可,密钥不用写在配置文件里,更安全。
set JASYPT_ENCRYPT_KEY=myBookKey123
2. 避坑:敏感配置加密的 2 个关键坑
错误 1:密钥写在配置文件里()—— 相当于把钥匙和锁一起给别人,加密白做了,解决:密钥必须存在环境变量或命令行参数里,别写配置文件;错误 2:密文没加
jasypt.encryptor.password=myBookKey123前缀 ——Spring Boot 不会识别为密文,会直接当作明文连接数据库,导致连接失败,解决:密文必须用
ENC()包裹。
ENC(密文内容)
四、配置管理避坑总结:新手必记的 5 个原则
环境隔离:开发 / 测试 / 生产配置分开,不用手动改配置,用激活;公共配置抽离:相同配置放主
spring.profiles.active,避免冗余;读取方式选对:单个配置用
application.yml,一组配置用
@Value,动态配置用
@ConfigurationProperties;敏感配置必加密:数据库密码、密钥等一定要用 jasypt 加密,密钥存环境变量;配置键命名规范:用小写 + 下划线(如
Environment),别用大写或驼峰,避免读取失败。
book.cache.expire
总结:配置管理的核心是 “有序、安全、灵活”
就像奶茶店的配方手册要 “分类清晰(多环境)、快速查询(配置读取)、核心保密(加密)”,Spring Boot 的配置管理也围绕这三点 —— 让你在不同环境下快速切换配置、想读配置时随手就能拿到、敏感信息不泄露,不用再为配置头疼。
掌握这些配置技巧,不管是小项目还是企业级项目,都能把配置管得明明白白,避免因配置问题导致上线翻车。


