SpringBoot 外部配置文件的使用和优先级
SpringBoot 提供了灵活的外部配置机制,让我们无需重新打包就能调整应用行为。本文梳理了几种常用的外部配置方式及其优先级关系,帮你在不同部署场景下做出正确选择。
改个端口号,还要重新打包?
你一定遇到过这种场景:项目打成 jar 包部署到服务器上,结果发现端口号冲突了,或者数据库地址要换。难道就为了改一行配置,要重新走一遍构建流程?当然不用。
SpringBoot 早就考虑到了这个问题,它提供了多种外部配置方式,让同一个 jar 包可以在不同环境中灵活运行。掌握这些配置方法和它们的优先级关系,是每个 SpringBoot 开发者的必备技能。
方式一:命令行参数
最简单粗暴的方式,直接在启动命令里加参数:
nohup java -jar myapp.jar --server.port=8081
这种方式适合临时调整,比如排查问题时临时换个端口,或者在不同终端启动多个实例。缺点也很明显——参数一多,命令行就变得又臭又长。
方式二:环境变量
在容器化部署(Docker、K8s)的场景下,环境变量是最主流的配置方式:
export SERVER_PORT=8081
java -jar myapp.jar
SpringBoot 会自动把环境变量映射到对应的配置属性上。规则也很简单:把属性名中的点换成下划线,字母全大写。比如 server.port 对应 SERVER_PORT,spring.datasource.url 对应 SPRING_DATASOURCE_URL。
这种方式的好处是配置和代码完全解耦,特别适合 12-Factor App 的理念。
方式三:外部配置文件
当需要修改的配置项比较多时,外部配置文件是最合适的选择。
放在 jar 包同级目录
最省事的做法:在 jar 包所在目录创建 application.yml 或 application-{profile}.yml,SpringBoot 启动时会自动加载它,并且优先级高于 jar 包内部的同名文件。
指定配置文件路径
如果配置文件放在别的目录,用 --spring.config.location 来指定:
java -jar myapp.jar --spring.config.location=file:/path/to/application.yml
追加额外配置
有时候你不想替换默认配置,只想在默认基础上加一些覆盖项。这时候用 --spring.config.additional-location:
java -jar myapp.jar --spring.config.additional-location=file:/path/to/application-prod.yml --spring.profiles.active=prod
这两个参数的区别很关键:location 会完全替换默认的配置搜索路径,而 additional-location 是在默认路径之外追加。搞混了会导致很多默认配置失效,排查起来很头疼。
配置加载优先级
说了这么多配置方式,那它们之间冲突了怎么办?SpringBoot 有一套明确的优先级规则(从高到低):
- 命令行参数
- Java 系统属性
- 操作系统环境变量
application-{profile}.properties外部文件application.properties外部文件application-{profile}.properties内部文件application.properties内部文件
核心原则就一句话:越「外部」的配置,优先级越高。命令行参数最高,jar 包内部的配置文件最低。同名属性会被高优先级的覆盖,不同名的则会合并。
还有两点容易踩坑:
--spring.config.location会完全替换默认的配置位置,用的时候要小心--spring.config.additional-location是追加,不会影响默认配置的加载- 后加载的配置会覆盖先加载的同名配置
小结
回到开头的问题——改配置不需要重新打包,只需要选择合适的外部配置方式。日常开发中,我的习惯是:开发环境用 jar 包内部的默认配置,测试和生产环境通过外部配置文件覆盖,临时调试用命令行参数。理解了优先级规则,配置管理就不会乱。