刚接手一个Spring Boot项目,兴冲冲地拉下代码,一运行就报错:‘Failed to bind properties’。一看日志,原来是数据库连接地址在测试环境和生产环境之间来回打架。这种问题太常见了,说到底还是环境配置没整明白。
为啥要分环境?
开发时连本地MySQL,测试时走CI/CD流水线,上线后又得切到生产库。如果所有配置写死在一个文件里,改来改去迟早出错。Spring Boot支持多环境配置,就是为了解决这个痛点。
application.yml 是怎么玩的?
默认情况下,Spring Boot会加载 application.yml 或 application.properties。但如果你有多个环境,可以拆成:
application.yml—— 公共配置application-dev.yml—— 开发环境application-test.yml—— 测试环境application-prod.yml—— 生产环境
比如公共部分定义端口:
server:
port: 8080
开发环境单独配置数据源:
# application-dev.yml
spring:
datasource:
url: jdbc:mysql://localhost:3306/myapp_dev
username: root
password: dev123
生产环境换一套:
# application-prod.yml
spring:
datasource:
url: jdbc:mysql://prod-db.company.com:3306/myapp
username: prod_user
password: ${DB_PASSWORD}
怎么指定用哪个环境?
在 application.yml 里激活对应配置就行:
spring:
profiles:
active: dev
也可以通过启动参数覆盖:
java -jar myapp.jar --spring.profiles.active=prod
或者设置环境变量:
export SPRING_PROFILES_ACTIVE=prod
敏感信息别往代码库里扔
密码、密钥这类东西,直接写在yml里风险太大。推荐做法是用环境变量注入,像上面的 ${DB_PASSWORD},运行时从容器或CI平台传进去。K8s里可以用Secret,Docker Compose也能通过env_file管理。
profile命名不是随便来的
有些人图省事写个 application-local.yml,结果发现不生效。注意Spring Boot只认注册过的profile名称。如果你写了 spring.profiles.active=local,就得确保存在对应的配置文件,否则会默默回退到默认配置,问题就藏得更深了。
配置加载顺序你得心里有数
Spring Boot有一套默认的加载优先级。外部配置能覆盖内部配置。比如你打包时带着 application.yml,但运行时放在jar同级目录再放一个同名文件,它会自动读取外部的那个。这条规则在运维上特别有用——不用重新打包就能改配置。
YAML缩进错了也跑不起来
有一次项目启动失败,提示‘Invalid config’,查了半天才发现是yml里少了个空格:
spring:
datasource:url: jdbc:mysql://...
正确写法必须对齐:
spring:
datasource:
url: jdbc:mysql://...
YAML靠缩进表达层级,差一个空格都能让你折腾半天。
验证配置是否生效的小技巧
加个简单的Controller,把关键配置打印出来:
@RestController
public class ConfigCheck {
@Value("${spring.datasource.url}")
private String dbUrl;
@GetMapping("/debug")
public String show() {
return "DB: " + dbUrl;
}
}
本地跑一下 curl localhost:8080/debug,一眼看出当前用的是哪套配置。
环境配置看着简单,真出问题能让你通宵。把这些细节理清楚,下次改配置时手就不会抖了。